从 shell 中的文件的每一行中删除字符

Remove characters from every line of a file in shell

我有一个 shell 脚本,它正在逐行读取变量的值。我需要从每一行中删除某些字符。

我有什么 - $sample_variable -

Data 0 start; 1 ABCD0;2 EFGH0;3 IJKL0;4 MNOP0;5 QRST0;6 end;

我想要的 -

start
ABCD0
EFGH0
IJKL0
MNOP0
QRST0
end

我写的代码 -

IFS=$';' 
for j in $sample_variable
do  
    j=$j | cut -d ' ' -f3-
    echo $j
    j=${j// /''}
    echo $j
    echo $j >> output.txt
done

我正在将输出写入 txt file.But,文件被写为 output.txt -

start
1ABCD0
2EFGH0
3IJKL0
4MNOP0
5QRST0
6end

如何删除开头出现的数字?

您也需要删除 space 前面的所有内容:

j=${j//* /''}

''不需要。

j=${j//* /}

*匹配任意数量的任意字符。所以如果 j 有两个 space,那么它将删除前面的所有内容,包括第二个 space。根据您的需要,使用可能会更好:

j=${j##* }

j=${j#* }

参见 shell parameter expansion in bash

读取数组中的变量然后处理可能会更好:

sample_variable='1 ABCD;2 EFGH;3 IJKL;4 MNOP;5 QRST;'
IFS=';' read -r -a arr <<<"$sample_variable"

然后你可以分割变量忽略第一个前面的任何东西space:

for j in "${arr[@]}"; do
     j=${j//* /}
     echo "$j"
done

但我只会执行以下操作,但它会留下一个空的尾随换行符,因此可能需要 sed '$d' - 删除最后一行:

<<<"$sample_variable" tr ';' '\n' | cut -d' ' -f2- | sed '$d'

备注:

  • j=$j | cut -d ' ' -f3- 并不像您想象的那样。它执行 j=$j 将变量设置为自身。然后它在没有输入的情况下执行 cut -d ' ' -f3-,因为赋值不打印任何输出。
  • 记得总是引用你的变量扩展。

如果您尝试删除所有数字,我会说您可以尝试使用 tr 工具,如下所示:

IFS=$';' for j in $sample_variable do j=$j | cut -d ' ' -f3- echo $j j=${j// /''} echo $j | tr -d [:digit:] echo $j | tr -d [:digit:] >> output.txt done

但是,如果您只想删除初始数字,则需要更通用的工具,例如 sed,它看起来像:

IFS=$';' for j in $sample_variable do j=$j | cut -d ' ' -f3- echo $j j=${j// /''} echo $j | sed -e 's/^[0-9]\?//' echo $j | sed -e 's/^[0-9]\?//' >> output.txt done

您可能会发现 sed 也很方便,

sample_data="Data 0 start 1 ABCD0;2 EFGH0;3 IJKL0;4 MNOP0;5 QRST0;6 end"
sed -e 's/^[^0]*0\ //' -e 's/;/\n/g' -e 's/\(^[^0-9][^0-9]*\ \)/\n/' -e 's/\ //g'

例子Use/Output

$ sample_data="Data 0 start 1 ABCD0;2 EFGH0;3 IJKL0;4 MNOP0;5 QRST0;6 end"
> echo "$sample_data" |
> sed -e 's/^[^0]*0\ //' -e 's/;/\n/g' -e 's/\(^[^0-9][^0-9]*\ \)/\n/' -e 's/\ //g'
start
1ABCD0
2EFGH0
3IJKL0
4MNOP0
5QRST0
6end

下面的代码解决了问题 -

i=0
IFS=$';' 
for j in $sample_variable
do 
    j=${j// /''}
    j=$(echo "$j" | tr -d [$i] | tr -d ["\n"])
    echo "$j" >> output.txt
    i=$((i+1))
done
}

因此,我采用了一个变量 'i',它将在循环中不断迭代。使用该变量,我能够删除仅出现在每一行开头的数字。