删除文本文件中的符号

时间:2018-10-24 17:37:33

标签: bash shell command-line scripting sh

我有一个文本文件test.txt,我想通过Bash脚本进行编辑。

想法是从/dev/stdin中读取一个字符串,然后将其用于删除以该字符串开头的所有行。我该如何实现?

到目前为止,我有以下内容:

#!/bin/bash
cat test.txt
echo "Write del if you want to delete or write save if you want to save"
read s1
echo "Which symbol"
read s2

if [ "$s1" = "save" ]; then
   sed -i '/^'$s2'/!d' test.txt    
elif [ "$s1" = "del" ]; then

fi 
cat test.txt

2 个答案:

答案 0 :(得分:1)

  

更新

#!/bin/bash

case "$#" in
2) s1="$1"; s2="$2";;
*) echo "$0 {save|del} <key>"
   exit 1;;
esac

case "$s1" in
save) v=-v ;;
del)  v=   ;;
esac

sed -in "$(cut -c -${#s2} x | grep $v -F -n "$s2" | sed "s/:.*/ d;/" )" test.txt

这处理复杂的前导元字符字符串。 :)

  

旧东西

我要将test.txt复制到可编辑的临时文件,以便获得一致的测试源。我也将args放在命令行上,因为我厌倦了分别键入它们并想循环测试。

是的,我知道您正在阅读stdin,但是您可以正常工作,并且可以根据需要将其放回原处。

哦,我喜欢案例陈述。 :)

#!/bin/bash

case "$#" in
2) s1="$1"; s2="$2";;
*) echo "$0 {save|del} <key>"
   exit 1;;
esac

# make a var that is $s2 but with these metacharacters removed
tst="$( echo "$s2" | tr -d "[/.;\][}{!#^&*)(-?\\\\]" )"
case "$tst" in 
$s2) q=''   ;; # if it's the same, no metas to worry about
  *) q="\\" ;; # else we need to quote the character
esac

cat test.txt >| edited
case "$s1" in
save) sed -in "/^$q$s2/!d" edited ;;
del)  sed -in "/^$q$s2/d"  edited ;;
esac

cat edited

即使您使用诸如/.之类的相关元字符,此方法也有效,因为它会引用它。该代码不需要从选项列表中排除任何字符。

我的源输入-

$: cat test.txt
foo1234567890qwertyuiopasdfghjklzxcvbnm
bar1234567890qwertyuiopasdfghjklzxcvbnm
/1234567890qwertyuiopasdfghjklzxcvbnm
&1234567890qwertyuiopasdfghjklzxcvbnm
|1234567890qwertyuiopasdfghjklzxcvbnm
.1234567890qwertyuiopasdfghjklzxcvbnm
?1234567890qwertyuiopasdfghjklzxcvbnm

我的测试示例:

$: for cmd in save del
   do for k in foo \/ \. \? \& \|
   do echo "
  =====  $cmd $k
   "
   script $cmd "$k"
   done
   done

  =====  save foo

foo1234567890qwertyuiopasdfghjklzxcvbnm

  =====  save /

/1234567890qwertyuiopasdfghjklzxcvbnm

  =====  save .

.1234567890qwertyuiopasdfghjklzxcvbnm

  =====  save ?

?1234567890qwertyuiopasdfghjklzxcvbnm

  =====  save &

&1234567890qwertyuiopasdfghjklzxcvbnm

  =====  save |

|1234567890qwertyuiopasdfghjklzxcvbnm

  =====  del foo

bar1234567890qwertyuiopasdfghjklzxcvbnm
/1234567890qwertyuiopasdfghjklzxcvbnm
&1234567890qwertyuiopasdfghjklzxcvbnm
|1234567890qwertyuiopasdfghjklzxcvbnm
.1234567890qwertyuiopasdfghjklzxcvbnm
?1234567890qwertyuiopasdfghjklzxcvbnm

  =====  del /

foo1234567890qwertyuiopasdfghjklzxcvbnm
bar1234567890qwertyuiopasdfghjklzxcvbnm
&1234567890qwertyuiopasdfghjklzxcvbnm
|1234567890qwertyuiopasdfghjklzxcvbnm
.1234567890qwertyuiopasdfghjklzxcvbnm
?1234567890qwertyuiopasdfghjklzxcvbnm

  =====  del .

foo1234567890qwertyuiopasdfghjklzxcvbnm
bar1234567890qwertyuiopasdfghjklzxcvbnm
/1234567890qwertyuiopasdfghjklzxcvbnm
&1234567890qwertyuiopasdfghjklzxcvbnm
|1234567890qwertyuiopasdfghjklzxcvbnm
?1234567890qwertyuiopasdfghjklzxcvbnm

  =====  del ?

foo1234567890qwertyuiopasdfghjklzxcvbnm
bar1234567890qwertyuiopasdfghjklzxcvbnm
/1234567890qwertyuiopasdfghjklzxcvbnm
&1234567890qwertyuiopasdfghjklzxcvbnm
|1234567890qwertyuiopasdfghjklzxcvbnm
.1234567890qwertyuiopasdfghjklzxcvbnm

  =====  del &

foo1234567890qwertyuiopasdfghjklzxcvbnm
bar1234567890qwertyuiopasdfghjklzxcvbnm
/1234567890qwertyuiopasdfghjklzxcvbnm
|1234567890qwertyuiopasdfghjklzxcvbnm
.1234567890qwertyuiopasdfghjklzxcvbnm
?1234567890qwertyuiopasdfghjklzxcvbnm

  =====  del |

foo1234567890qwertyuiopasdfghjklzxcvbnm
bar1234567890qwertyuiopasdfghjklzxcvbnm
/1234567890qwertyuiopasdfghjklzxcvbnm
&1234567890qwertyuiopasdfghjklzxcvbnm
.1234567890qwertyuiopasdfghjklzxcvbnm
?1234567890qwertyuiopasdfghjklzxcvbnm

这仍然存在开头字符串由多个元字符组成的情况的问题……我在考虑那个问题……

因此,备用版本:

#!/bin/bash

case "$#" in
2) s1="$1"; s2="$2";;
*) echo "$0 {save|del} <pattern>"
   exit 1;;
esac

cat test.txt >| edited
case "$s1" in
save) act="!d" ;;
del)  act="d"  ;;
esac
sed -in "$s2$act"  edited

cat edited

这意味着您必须(正确地)在命令行中放入搜索模式,但是您可以处理任何喜欢的怪异现象。例如,我添加了一行-

/.?1234567890qwertyuiopasdfghjklzxcvbnm

并以script save "/^[/][.][?]/"的身份运行,效果很好。

答案 1 :(得分:0)

我已阅读了一些评论,并决定修改我的答案。我的新答案如下:

sed '/^'${s2//\//\\/}'/d'

基于kvantour的评论,这也是一种可行的解决方案:

sed -i '/^'${s2//\//\\/}'/d' test.txt

原始答案:(请参阅评论)

所以这是因为您引用变量(又称变量)的方式,我有一些想法可以改用。让我知道他们中的任何一个是否有效:

1.sed '/^$s2/ d'
2.sed "/^$s2/ d"
3.sed "/^'$s2'/ d"
4.sed -i "|^'$s2'| d" test.txt