我有什么
我在脚本中过多地记录了我的元语句。有很多。它们都是这样开头的:
#!/bin/bash
# Title and other notes information
## I may have other lines here, or not
ruler=( monarch ) # Type of leader
kingdom=( "Island" ) # Type of territory
zipcode=( 90210 ) # Standard, 3-12 digits, hyphens allowed
datatype=( 0-9- ) # Datatype
favoritepie=( "Cherry" ) # A happy memory
aoptions=( "Home address" "Work address" "Mobile" ) # List custom options
boptions=( ) # List secondary options
aopttypes=( string string phonenum ) # Corresponding datatypes for options
bopttypes=( ) # Corresponding datatypes for secondary options
sourced=( ) # Sourced text in this script, such as settings
subscripts=( installusr ) # Valid BASH scripts that this script may call
...
# Script continues
outsidethewire=( "key 971" ) # Leave this comment here
somearray=( "sliced apples" "pie dough" ) # Mother's secret recipe
…我要把它变成这样……
#!/bin/bash
# Title and other notes information
## I may have other lines here, or not
ruler=( monarch )
kingdom=( "Island" )
zipcode=( 90210 )
datatype=( 0-9- )
favoritepie=( "Cherry" )
aoptions=( "Home address" "Work address" "Mobile" )
boptions=( )
aopttypes=( string string phonenum )
bopttypes=( )
sourced=( )
subscripts=( installusr )
...
# Script continues
outsidethewire=( "key 971" ) # Leave this comment here
somearray=( "sliced apples" "pie dough" ) # Mother's secret recipe
- 只有11行这样的,它们是这样的。
- 这些行之前可能会有注释,但是11个数组之前的行数因脚本而异。
- 每条评论都以一致的模式
) #
… 开始
我需要的
我需要删除这些数组语句后面的注释。
我有什么
我可以运行这个…
sed 's/ ) # .*/ )/' *
但是,我想将其限制为每个文件只出现前11次。
从这个答案我得到一个模式匹配第一个单一的匹配,给我这个…
sed '0,/ ) # .*/s// )/' *
…但这只适用于第一次出现。
我可以把它放入一个循环:
#!/bin/bash
counter=1
while [ "$counter" -le "11" ]; do
sed '0,/ ) # .*/s// )/' *
counter=$(expr $counter + 1)
done
这样"合适"吗?
此循环假设所有文件将均匀匹配,对所有文件都空白运行。如果可能的话,我希望循环对每个文件运行,而不是基于计数器对所有文件运行。但是,我不知道该怎么做。
这是最好的方法吗?或者,是否有一种使用其他Linux工具的更"合适"、更安全的方法?
如果我理解正确的话,您想要匹配右括号)
之后的注释,并删除文件中的前11个注释,而不管右括号之后是否出现类似的匹配。
假设文件的内容是;
$ cat input_file
#!/bin/bash
# Title and other notes information
## I may have other lines here, or not
ruler=( monarch ) # Type of leader
kingdom=( "Island" ) # Type of territory
zipcode=( 90210 ) # Standard, 3-12 digits, hyphens allowed
datatype=( 0-9- ) # Datatype
favoritepie=( "Cherry" ) # A happy memory
aoptions=( "Home address" "Work address" "Mobile" ) # List custom options
boptions=( ) # List secondary options
aopttypes=( string string phonenum ) # Corresponding datatypes for options
bopttypes=( ) # Corresponding datatypes for secondary options
sourced=( ) # Sourced text in this script, such as settings
subscripts=( installusr ) # Valid BASH scripts that this script may call
# Title and other notes information
## I may have other lines here, or not
ruler=( monarch ) # Type of leader
kingdom=( "Island" ) # Type of territory
zipcode=( 90210 ) # Standard, 3-12 digits, hyphens allowed
datatype=( 0-9- ) # Datatype
favoritepie=( "Cherry" ) # A happy memory
aoptions=( "Home address" "Work address" "Mobile" ) # List custom options
boptions=( ) # List secondary options
aopttypes=( string string phonenum ) # Corresponding datatypes for options
bopttypes=( ) # Corresponding datatypes for secondary options
sourced=( ) # Sourced text in this script, such as settings
subscripts=( installusr ) # Valid BASH scripts that this script may call
...
# Script continues
使用sed
,然后匹配感兴趣的行,对符合条件的前11行执行操作。
$ sed '/) #/{1,+10s/#.*//}' input_file
#!/bin/bash
# Title and other notes information
## I may have other lines here, or not
ruler=( monarch )
kingdom=( "Island" )
zipcode=( 90210 )
datatype=( 0-9- )
favoritepie=( "Cherry" )
aoptions=( "Home address" "Work address" "Mobile" )
boptions=( )
aopttypes=( string string phonenum )
bopttypes=( )
sourced=( )
subscripts=( installusr )
# Title and other notes information
## I may have other lines here, or not
ruler=( monarch ) # Type of leader
kingdom=( "Island" ) # Type of territory
zipcode=( 90210 ) # Standard, 3-12 digits, hyphens allowed
datatype=( 0-9- ) # Datatype
favoritepie=( "Cherry" ) # A happy memory
aoptions=( "Home address" "Work address" "Mobile" ) # List custom options
boptions=( ) # List secondary options
aopttypes=( string string phonenum ) # Corresponding datatypes for options
bopttypes=( ) # Corresponding datatypes for secondary options
sourced=( ) # Sourced text in this script, such as settings
subscripts=( installusr ) # Valid BASH scripts that this script may call
...
# Script continues
如果我正确理解了您的要求,下面将工作:
#!/bin/bash
for file in *; do
temp=$(mktemp tmp.XXXXXX)
awk '
/)[[:space:]]*#/ && c++ < 11 {sub(/[[:space:]]*#.*/, "")}
1
' "$file" > "$temp"
mv -f -- "$file" "$file".O # backup file
mv -f -- "$temp" "$file"
done
如果GNU awk
可用,-i inplace
选项将覆盖文件,而不是创建临时文件:
#!/bin/bash
for file in *; do
gawk -i inplace -v inplace::suffix=.O '
/)[[:space:]]*#/ && c++ < 11 {sub(/[[:space:]]*#.*/, "")}
1
' "$file"
done
或简单的:
#!/bin/bash
gawk -i inplace -v inplace::suffix=.O '
/)[[:space:]]*#/ && c++ < 11 {sub(/[[:space:]]*#.*/, "")}
1
' *
这可能适合您(GNU sed):
sed -E 'x;/x{11}/{x;b};x;/) #.*/{s//)/;x;s/^/x/;x}' file
本质上,在保持空间中保留一个计数器,如果所需类型的11条注释已被删除,则不需要进一步处理一行。
检查等待空间计数器,如果是11,就跳伞。
否则,如果该行符合所需的条件,则删除注释并增加保持空间中的计数器。
在所有其他情况下,不进行任何处理。