Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何删除与数组中共享的字符串匹配的行_Linux_Bash - Fatal编程技术网

Linux 如何删除与数组中共享的字符串匹配的行

Linux 如何删除与数组中共享的字符串匹配的行,linux,bash,Linux,Bash,我有一个由如下文本组成的文件 compile_tool/opt/CSDTK/bin/chipgen/Modem2G/toolpool/plugins/Calib/libcalibplugin.so compile_tool/opt/CSDTK/bin/chipgen/Modem2G/toolpool/plugins/Calib/libcalibplugin.dill compile_tool/opt/CSDTK/bin/lib/ruby/gems/1.8/gems/builder-2.1.2/R

我有一个由如下文本组成的文件

compile_tool/opt/CSDTK/bin/chipgen/Modem2G/toolpool/plugins/Calib/libcalibplugin.so
compile_tool/opt/CSDTK/bin/chipgen/Modem2G/toolpool/plugins/Calib/libcalibplugin.dill
compile_tool/opt/CSDTK/bin/lib/ruby/gems/1.8/gems/builder-2.1.2/Rakefile.pg
compile_tool/opt/mingw32_3.4.4/usr/i586-mingw32msvc/include/mmsystem.c
compile_tool/opt/mingw32_3.4.4/usr/i586-mingw32msvc/include/winnt.h
compile_tool/opt/CSDTK/bin/lib/ruby/gems/1.8/gems/builder-2.1.2/test/test_xchar.HEX
我想删除文件扩展名为.so、.dill、.pg和.HEX的行。我试过下面的代码,但没有成功

#! /bin/bash
array=(.a .so .bin.ihex .dll .exe .gem .bin .png .HEX)
for a in "${array[@]}"
do 
sed -i -e "/\$a\b/d" copyright
done 
不必为每个扩展调用一次sed,您可以使用以下方法:

IFS=$'\n'
grep -F -v "${array[*]}" copyright
如果其输出看起来不错,请将其重定向到一个文件,并将其名称更改为copyright,必要时恢复IFS。

您可以使用以下方法,而不是为每个扩展名调用一次sed:

IFS=$'\n'
grep -F -v "${array[*]}" copyright
如果其输出看起来不错,请将其重定向到一个文件,并将其名称更改为版权,必要时恢复IFS。

如果您的sed支持正则表达式中的\|或运算符,请尝试:

array=(.a .so .bin.ihex .dll .exe .gem .bin .png .HEX)
pat="$(IFS='|'; echo "${array[*]}" | sed -e 's/|/\\|/g' -e 's/\./\\./g')"
sed "/\($pat\)\$/d" copyright
它连接数组元素并生成一个模式字符串,看起来像:\.a\\\\.so\\.bin\.ihex\\\\。。。。 然后sed/\$pat\\$/d行文本删除与模式匹配的行。 请注意,您的数组元素和具有文件扩展名.so、.dill、.pg和.HEX的文本行可能不一致。我已按原样使用了您的数组。

如果您的sed支持正则表达式中的\| or运算符,请尝试:

array=(.a .so .bin.ihex .dll .exe .gem .bin .png .HEX)
pat="$(IFS='|'; echo "${array[*]}" | sed -e 's/|/\\|/g' -e 's/\./\\./g')"
sed "/\($pat\)\$/d" copyright
它连接数组元素并生成一个模式字符串,看起来像:\.a\\\\.so\\.bin\.ihex\\\\。。。。 然后sed/\$pat\\$/d行文本删除与模式匹配的行。
请注意,您的数组元素和具有文件扩展名.so、.dill、.pg和.HEX的文本行可能不一致。我已经按原样使用了您的阵列。

根据Oguz Ismail的回答,从与他讨论的想法开始:

无论您是使用grep-e还是sed来标识保存的文件,问题是在这两种情况下,数组的元素都被解释为正则表达式。例如,您有一个数组元素.a,作为regexp,这意味着它将匹配任何包含字母“a”的文件,但文件名开头除外。因此,main.c行也将与pattern.a匹配

一种可能性是使用通配符匹配而不是regexp匹配,但这意味着您需要显式循环数组:例如,要测试$line行是否将被删除或应保留,您必须执行以下操作:

line_matches_pat=no
for pat in "${array[@]}"
do
  if [[ $line == *$pat ]]
  then
    line_matches_pat=yes
    break
  fi
done
如果$line_matches_pat等于yes,则该行与数组中的一个模式匹配

在我看来,更明智、更灵活的方法是在数组中存储您感兴趣的文件的正则表达式,而不是文件的扩展名。这使您有一天可以在列表中输入类似于包含字符串error_uu并具有扩展名.c的文件名的内容。当您这样做时,您可以使用类似于@oguzismail建议的解决方案的方法,但是您当然不能再将-F与grep一起使用了:

grep -E -v "${array[*]}" copyright

这将打开扩展正则表达式。如果你对简单的正则表达式没问题,请删除-E。

从Oguz Ismail根据他的答案讨论的想法开始:

无论您是使用grep-e还是sed来标识保存的文件,问题是在这两种情况下,数组的元素都被解释为正则表达式。例如,您有一个数组元素.a,作为regexp,这意味着它将匹配任何包含字母“a”的文件,但文件名开头除外。因此,main.c行也将与pattern.a匹配

一种可能性是使用通配符匹配而不是regexp匹配,但这意味着您需要显式循环数组:例如,要测试$line行是否将被删除或应保留,您必须执行以下操作:

line_matches_pat=no
for pat in "${array[@]}"
do
  if [[ $line == *$pat ]]
  then
    line_matches_pat=yes
    break
  fi
done
如果$line_matches_pat等于yes,则该行与数组中的一个模式匹配

在我看来,更明智、更灵活的方法是在数组中存储您感兴趣的文件的正则表达式,而不是文件的扩展名。这使您有一天可以在列表中输入类似于包含字符串error_uu并具有扩展名.c的文件名的内容。当您这样做时,您可以使用类似于@oguzismail建议的解决方案的方法,但是您当然不能再将-F与grep一起使用了:

grep -E -v "${array[*]}" copyright

这将打开扩展正则表达式。如果你对简单的正则表达式没问题,请删除-E。

与@tshiono建议的相同,但使用printf构建模式

printf -v pat '\%s\|' ${array[@]}
sed "/${pat%*'\|'}/d" copyright

与@tshiono建议的相同,但使用printf构建模式

printf -v pat '\%s\|' ${array[@]}
sed "/${pat%*'\|'}/d" copyright

@oguzismail:这也会删除一行,比如abc.sox.txt。数组中的扩展名需要在文件名的末尾匹配。也许我们必须首先转换数组,在末尾添加$,然后从grep中省略-F。@user1934428是的,我只是假设OP的输入中没有这样的行。为了涵盖这些情况,以及在元素中添加$,我们也需要逃逸;否则的话,比如说$也会和abc.iso匹配,你是对的。也许是一个更明智的选择,最终也更明智
灵活的方法是让files.txt包含egrep模式,而不是文件名。@oguzismail:这也会删除一行,比如abc.sox.txt。数组中的扩展名需要在文件名的末尾匹配。也许我们必须首先转换数组,在末尾添加$,然后从grep中省略-F。@user1934428是的,我只是假设OP的输入中没有这样的行。为了涵盖这些情况,以及在元素中添加$,我们也需要逃逸;否则的话,比如说$也会和abc.iso匹配,你是对的。也许一种更明智、更灵活的方法是让files.txt包含egrep模式,而不是文件名。