在Bash中删除字符串的第一个字符

Jos*_*siP 33 bash

我需要计算ls转储中每行的一个字符串(pathfile)的md5sum directory_listing_file:

./r/g4/f1.JPG
./r/g4/f2.JPG
./r/g4/f3.JPG
./r/g4/f4.JPG
Run Code Online (Sandbox Code Playgroud)

但是应该在没有初始点的情况下计算md5sum.我写了一个简单的脚本:

while read line
do
    echo $line | exec 'md5sum'
done

./g.sh < directory_listnitg.txt
Run Code Online (Sandbox Code Playgroud)

如何从每行中删除第一个点?

小智 67

myString="${myString:1}"
Run Code Online (Sandbox Code Playgroud)

从myString的字符编号1开始(字符0是最左边的字符)返回字符串的剩余部分."s允许字符串中的空格.有关该方面的更多信息,请查看$ IFS.

  • 这个答案是最快的,因为它是纯粹的bash.其他人为所有字符串运行外部进程.如果您只有少量字符串要处理,这一点就不重要了,但如果你有很多字符串而且工作量很少(平均每个字符串),这一点很重要. (2认同)
  • 这也是更普遍的,因此可以应用于更多的情况。应该是公认的答案。 (2认同)

ful*_*ton 23

你可以把它管道

cut -c2-
Run Code Online (Sandbox Code Playgroud)

哪个给你

while read line
do
echo $line | cut -c2- | md5sum
done

./g.sh < directory_listnitg.txt
Run Code Online (Sandbox Code Playgroud)

  • 对于那些想知道这== syntax =到底意味着什么的人,`-c2-`参数可以解释为:返回字符(`-c`),从第二个开始直到最后一个“ 2-”,例如其他示例可以是范围为-c2-5或单个字母为-c3。从末尾减少计数,[使用](https://unix.stackexchange.com/a/64673/144997)`rev | 切.. | 转速 (3认同)

Iva*_*van 8

或者像这样

myString="${myString/.}"
Run Code Online (Sandbox Code Playgroud)

在 Ubuntu 18.04.4 LTS、bash 4.4.20 上测试:

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.4 LTS
Release:    18.04
Codename:   bionic

$ echo $BASH_VERSION
4.4.20(1)-release

$ myString="./r/g4/f1.JPG"
$ myString="${myString/.}"
$ echo $myString
/r/g4/f1.JPG
Run Code Online (Sandbox Code Playgroud)

此命令将删除任何第一个字符:

echo ${myString/?}
Run Code Online (Sandbox Code Playgroud)


小智 6

从行或字符串中删除前 n 个字符

#method1) 使用 bash

 str="price: 9832.3"
 echo "${str:7}"
Run Code Online (Sandbox Code Playgroud)

#method2) 使用切割

 str="price: 9832.3"
 cut -c8- <<< $str
Run Code Online (Sandbox Code Playgroud)

#method3) 使用 sed

 str="price: 9832.3"
 cut -c8- <<< $str
Run Code Online (Sandbox Code Playgroud)

#method4) 使用 awk

 str="price: 9832.3"
 awk '{gsub(/^.{7}/,"");}1' <<< $str
Run Code Online (Sandbox Code Playgroud)

  • 您最终为 cut 和 sed 发出了相同的命令;尽管如此,非常有用!+1 (7认同)

Fre*_*ihl 5

不同的方法,使用 sed,它的好处是它可以处理不以点开头的输入。此外,您不会遇到echo在输出中附加换行符的问题,这将导致 md5sum 报告虚假结果。

#!/bin/bash

while read line
do
     echo -n $line | sed 's/^.//' | md5sum
done < input
Run Code Online (Sandbox Code Playgroud)

比较这些:

$ echo "a" | md5sum
60b725f10c9c85c70d97880dfe8191b3  -

$ echo -n "a" | md5sum
0cc175b9c0f1b6a831c399e269772661  -
Run Code Online (Sandbox Code Playgroud)


l0b*_*0b0 5

将字段分隔符设置为路径分隔符,并读取除第一个斜杠之前的内容之外的所有内容$name

while IFS=/ read junk name
do
    echo $name
done < directory_listing.txt
Run Code Online (Sandbox Code Playgroud)


mik*_*erv 5

您可以像这样做整个事情:

% sh -c `sed 's@^.\(.*\)@md5sum \1@' <./dirlist.txt`
Run Code Online (Sandbox Code Playgroud)

确实,我认为您可以提高效率,但是我不知道是什么在生成您的列表。如果您可以pipe从中执行此操作,或者通过a运行该命令heredoc以保持其输出正常,则可能可以完成整个工作流。

编辑:

好的,您说这是来自“ ls转储”。好吧,这里有些灵活:

% ls_dump() {
> sed 's@^.\(.*\)$@md5sum \1@' <<_EOF_ | sh -s
>> `ls ${@}`
>> _EOF_
> }
% ls_dump -all -args -you /would/normally/give/ls
<desired output>
Run Code Online (Sandbox Code Playgroud)

我认为这总共只调用了一个子外壳。它应该是相当不错的,但是在我看来,find ... -exec md5sum {} ... +它可能更安全,更快,并且满足您的所有需求。

编辑2:

好的,现在我将回答这个问题。要删除任何POSIX兼容外壳程序中字符串的第一个字符,您只需要查看参数扩展即可,例如:

${string#?}
Run Code Online (Sandbox Code Playgroud)

-麦克风

  • 很棒的命令,刚刚找到了适合我的情况的解决方案。我必须使用 POSIX shell 删除字符串的前 3 个字符,而 `${string#???}` 对我有用。谢谢! (2认同)

小智 5

有一种非常简单的方法可以实现这一点:

假设我们不想要变量中的前缀“i-”

$ ROLE_TAG=role                                                                            
$ INSTANCE_ID=i-123456789
Run Code Online (Sandbox Code Playgroud)

您只需要添加 '#'+[your_exclusion_pattern],例如:

$ MYHOSTNAME="${ROLE_TAG}-${INSTANCE_ID#i-}"  
Run Code Online (Sandbox Code Playgroud)
$ echo $MYHOSTNAME
role-123456789
Run Code Online (Sandbox Code Playgroud)