如何使用awk或sed
删除带有水平条和冒号(:)的路径之间的字符串示例输入:
"/data/loads/logs/131300_38153.log:459:"
期望的输出:
131300_38153.log
尝试:
echo "/data/loads/logs/131300_38153.log:459:"|sed -n 's/.*/data/loads/logs/\([^ ]*\):/\1/p'
答案 0 :(得分:2)
sed
中的问题是/
命令中嵌入了s///
。
这不起作用,因为它破坏了语法。
幸运的是,你可以用其他东西替换/
,
例如?
,而是使用s???
。
然后你可以嵌入/
(但不是?
),
像这样:
sed -n 's?.*/data/loads/logs/\([^ ]*\):?\1?p'
但这还不足以解决您的问题。
首先,您要删除:
之后的所有内容。
所以写:.*
。
而且,我认为你打算写[^ ]
而不是[^:]
。
这将有效:
sed -n 's?.*/data/loads/logs/\([^:]*\):.*?\1?p'
但为什么要用这么复杂的方式写呢?
根据样本输入,
你可以切断从开始到最后/
的所有事情,
然后切断从第一个:
到结束的所有内容。
sed -ne 's?.*/\([^/:]*\):.*?\1?p' <<< "$line"
顺便说一下,你可以只用Bash原生这个:
line="/data/loads/logs/131300_38153.log:459:"
line=${line##*/}
line=${line%%:*}
echo "$line"
答案 1 :(得分:0)
使用sed
$ echo "/data/loads/logs/131300_38153.log:459:" | sed -E 's/(^\/.*\/)(.*)(:.*:)/\2/'
131300_38153.log
使用awk
$ echo "/data/loads/logs/131300_38153.log:459:" | awk -F'[/|:]' '{print $5}'
答案 2 :(得分:0)
使用AWK轻松
echo "/data/loads/logs/131300_38153.log:459:" | awk -F : '{print $1}' | awk -F / '{print $NF}'
答案 3 :(得分:0)
尝试关注awk和sed解决方案,这可以帮助您解决问题。
解决方案1:使用awk的替代功能。
echo "/data/loads/logs/131300_38153.log:459:" | awk '{sub(/.*\//,"");sub(/:.*/,"");print}'
解决方案第二:使用awk的匹配功能,我们将在其中提供正则表达式,然后打印匹配的值。
echo "/data/loads/logs/131300_38153.log:459:" | awk '{match($0,/[0-9].[^:]*/);print substr($0,RSTART,RLENGTH)}'
解决方案3:将RS(记录分隔符)值设置为/:
echo "/data/loads/logs/131300_38153.log:459:" | awk -v RS='[/:]' 'NR==5'
解决方案4:使用RS(记录分隔符)值作为/:然后将数字中的正则表达式与.log匹配以匹配确切的单词。
echo "/data/loads/logs/131300_38153.log:459:" | awk -v RS='[/:]' '/[0-9].*log/'
解决方案5:将自定义字段分隔符设置为字符串/数据/加载/日志或:
echo "/data/loads/logs/131300_38153.log:459:" | awk -F'/data/loads/logs/|:' '{print $2}'
解决方案6:通过使用sed命令将线分成多个部分并将它们保存在sed的临时内存中,并根据需要打印第二个必需的匹配项。
echo "/data/loads/logs/131300_38153.log:459:" | sed 's/\(.*\/\)\(.[^:]*\)\(.*\)/\2/'
答案 4 :(得分:0)
这可能适合你(GNU sed):
sed -n 's/.*\/\([^/:_]*_[^/:]*\):.*/\1/p' file
找到以/
开头的字符串,后跟零个或多个字符,这些字符不是/
,:
或_
后跟{{1} }后跟零个或多个字符,既不是_
,也不是/
后跟:
。如果发生替换,只打印这样的字符串。