我有一个与删除出现在n+2
匹配字符串之后位置的字符串相关的问题,该匹配字符串位于n
用于awk
多个文件的位置。我可以使用以下命令打印它:
awk -F '/radius-server/{nr[NR+4]}; NR in nr' *
其中匹配的字符串是radius-server
.由于我不太熟悉,
awk
如果有人可以帮助我,我将不胜感激就地删除这一行,这意味着我希望在删除完成后修改并保存文件。下面是一个示例场景 -
file 1
未经修改
radius-server dz7HQQH4EqT5 1645-1646
!
oj5icqh1dGpSK
!
alias exec t telnet
alias exec sis show interface status
!
file 2
,修改后为——
radius-server dz7HQQH4EqT5 1645-1646
!
!
alias exec t telnet
alias exec sis show interface status
!
我知道我可以使用模式匹配方法sed -i '/pattern/d'
来删除它,但这不是我想要的,因为值会随着文件的不同而变化。任何帮助将非常感激。
答案1
sed 似乎是正确的工具:
sed -i '/radius-server/!b;n;n;d' filename
怎么运行的:
/radius-server/!b # as long as it's NOT 'radius-server' do nothing (branch to end)
n # read next line (replace current line with next line)
n # same as above - we now read 2 lines
d # delete the current line
更新 - 要修改多个文件,只需使用 glob 而不是文件名,例如
sed -i '/radius-server/!b;n;n;d' *
答案2
除非你有 GNU awk 4.1.0 或更高版本...
您不会有像 sed-i
选项这样的选项,因此可以这样做:
对于 * 中的文件 做 awk -v 行=2 'BEGIN { 忽略 = -1 } /radius-server/ { 忽略 = NR + 行 } NR != 忽略 { print }' "$file" 完成 > 结果.txt
其工作原理如下:
BEGIN { ignore = -1 } # initialize ignore with -1 so NR will never
# be equal to it by accident
/radius-server/ { ignore = NR + lines } # when the radius-server is found, set ignore to the
# line we want to ignore
NR != ignore { print } # unless the current line is that line, print
# it.
注意:这-i
并不神奇,它还会创建一个临时文件,sed
只是为您处理它。
更新
如果需要递归到子目录:
寻找 。 -type f -exec awk ... {} ; > 结果.txt
在这两种情况下,您可能应该将 result.txt 放在不同的目录中。否则,它将被匹配并用作输入文件。
答案3
PATH_TO_FOLDER="/some/path/to/folder/"
FILE_EXTENSION=".ext"
FILES=$(ls ${PATH_TO_FOLDER}/*${FILE_EXTENSION})
for FILE in $FILES; do
FILENAME=$(basename $FILE ${FILE_EXTENSION})
TMP_FILE=${PATH_TO_FOLDER}/${FILENAME}.tmp
awk -v Lines=2 '{if($0~"radius-server"){
print;
for(i=0;i<=Lines;i++)
{
getline;
if(i==Lines){
next;
}else{
print;
}
}
}
else{
print;
}
}' $FILE > $TMP_FILE
mv ${TMP_FILE} ${FILE}
原则上这应该可行。基本上,如果该行包含 radius-server 将打印该行,然后它将迭代接下来的 3 行 0 将打印第一行 1 将打印第二行,然后 3 将完全跳过第三行。对于所有其他情况,这些行将按原样打印。