我有一个文本文件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
答案 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