我想破解一个bash脚本,该脚本在yad
弹出窗口中输出用户的PID,并根据需要选择和kill
PID。但是脚本使用awk
格式化数据,我不熟悉awk
。我会使用sed
代替,但数据有11个字段,sed
只允许9个缓冲区。
awk
格式的问题是最后一个字段,$11
是命令详细信息,它在描述中的第一个空格之后被切断,这是我不想要的。我想我可以在前10个之后替换所有空格,识别为字段分隔符,以防止命令描述细节在第一个空格后被删除。但这似乎有点hacky,我确信使用原始脚本中的awk
命令可以有一种更明智的方式:
function gen_data() {
ps aux | tail -n +2 > "$TMPFILE"
sed -ri "/$USER/!d" "$TMPFILE"
sed -ri "/$procName/!d" "$TMPFILE"
cat "$TMPFILE"
cat "$TMPFILE" | awk -F' ' '{print " " "\n" $1 "\n" $2 "\n" $3 "\n" $4 "\n" $5 "\n" $6 "\n" $7 "\n" $8 "\n" $9 "\n" $10 "\n" $11}' > "$OUTFILE"
#`sed` edit
#cat "$TMPFILE" | sed -r 's/^([^ ]*)[ ]{1,}([^ ]*)[ ]{1,}([^ ]*)[ ]{1,}([^ ]*)[ ]{1,}[^ ]*[ ]{1,}[^ ]*[ ]{1,}([^ ]*)[ ]{1,}([^ ]*)[ ]{1,}([^ ]*)[ ]{1,}([^ ]*)[ ]{1,}(.*)$/\1\n\2\n\3\n\4\n\5\n\6\n\7\n\8\n\9/' > "$OUTFILE"
cat "$OUTFILE"
}
我想知道是否有人介意帮忙解决这个问题?
更新
我设法通过使用while
循环来更改$TMPFILE
中的前十个空格,然后awk
将其处理为制表符,从而保留了我想要的输出,这样可以保留PID描述中的所有空格机智:
function gen_data() {
ps aux | tail -n +2 > "$TMPFILE"
sed -ri "/$USER/!d" "$TMPFILE"
sed -ri "/$procName/!d" "$TMPFILE"
cat "$TMPFILE"
cntr=10
while [[ "$cntr" -gt 0 ]] ; do
sed -ri 's/[ ]{1,}/\t/' "$TMPFILE"
((cntr--))
done
cat "$TMPFILE" | awk -F ' ' '{print " " "\n" $1 "\n" $2 "\n" $3 "\n" $4 "\n" $5 "\n" $6 "\n" $7 "\n" $8 "\n" $9 "\n" $10 "\n" $11}' > "$OUTFILE"
}
我仍然会对任何替代/更好的方式感兴趣吗?
答案 0 :(得分:2)
<强> EDITED 强>
抱歉,我今天傻了!假设它从第70列开始,你可以使用substr()
来获取命令:
awk '{command=substr($0,70); print command}' $TEMPFILE
另一个选项
您还可以获取与给定进程ID(pid)对应的命令,如下所示:
ps -p <PID> -xo command=
而不是删除所有不属于给定用户的行(就像你使用sed
一样),你可能首先使用这样的命令更具体:
ps -u <uid> -xo pid=,uid=,command=
原始回答
我认为您可以使用FIELDWIDTHS
变量告诉awk
分割字段的位置,而不是使用空格。它是一个GNU扩展,我不知道ps aux
命令中字段的宽度,所以你必须计算它们: - )
awk 'BEGIN{FIELDWIDTHS="14 8 6 6 6 8 6 8 6 8 200"}{print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11}' $TMPFILE
只需使最后一个字段的宽度很大,即可捕获所有命令。