[英]New to awk and sed, How could I improve this? Multiple sed and awk commands
這是我構建的腳本
它根據作為參數提供的擴展名獲取文件列表。
然后,它將刪除這些文件中模式00000000:之前的所有內容。
<pre>
,然后刪除了<pre>
五個字符。 if [[ $# -eq 0 ]] ; then echo 'Run script as ./hexconv ext' exit 0 fi for file in *.$1 do filename=$(basename $file) extension="${filename##*.}" filename="${filename%.*}" sed -n '/00000000:/,$p' $file | sed '1s/^.....//' | head -n -3 | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" "$10" "$11" "$12" "$13" "$14" "$15" "$16" "$17}' | xxd -p -r > $filename.jpg done
它也可以按我想要的方式工作,但是我懷疑有一些可以改進的地方,但是,a,我是awk和sed使用的新手。
摘錄自文件
<th>response-head:</th>
<td>HTTP/1.1 200 OK
Date: Sun, 15 Dec 2013 04:27:04 GMT
Server: PWS/8.0.18
X-Px: ms h0-s34.p6-lhr ( h0-s35.p6-lhr), ht-d h0-s35.p6-lhr.cdngp.net
Etag: "4556354-9fbf8-4e40387aadfc0"
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0
Accept-Ranges: bytes
Content-Length: 654328
Content-Type: image/jpeg
Last-Modified: Thu, 15 Aug 2013 21:55:19 GMT
Pragma: no-cache
</td>
</tr>
</table>
<hr/>
<pre>00000000: ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 48 ......JFIF.....H
00000010: 00 48 00 00 ff e1 00 18 45 78 69 66 00 00 49 49 .H......Exif..II
00000020: 2a 00 08 00 00 00 00 00 00 00 00 00 00 00 ff ed *...............
00000030: 00 48 50 68 74 73 68 70 20 33 2e 30 00 .HPhotoshop 3.0.
00000040: 38 42 49 4d 04 04 00 00 00 00 00 1c 01 5a 00 8BIM..........Z.
00000050: 03 1b 25 47 1c 02 00 00 02 00 02 00 38 42 49 4d ..%G........8BIM
00000060: 04 25 00 00 00 00 00 10 fc e1 89 c8 b7 c9 78 .%.............x
00000070: 34 62 34 07 58 77 eb ff e1 03 a5 68 74 74 70 /4b4.Xw.....http
00000080: 3a 6e 73 2e 61 64 62 65 2e 63 6d ://ns.adobe.com/
00000090: 78 61 70 31 2e 30 00 3c 78 70 61 63 6b xap/1.0/.<?xpack
000000a0: 65 74 20 62 65 67 69 6e 3d 22 ef bb bf 22 20 69 et begin="..." i
000000b0: 64 3d 22 57 35 4d 30 4d 70 43 65 68 69 48 7a 72 d="W5M0MpCehiHzr
000000c0: 65 53 7a 4e 54 63 7a 6b 63 39 64 22 3e 20 3c eSzNTczkc9d"?> <
000000d0: 78 3a 78 6d 70 6d 65 74 61 20 78 6d 6c 6e 73 3a x:xmpmeta xmlns:
000000e0: 78 3d 22 61 64 62 65 3a 6e 73 3a 6d 65 74 61 x="adobe:ns:meta
000000f0: 22 20 78 3a 78 6d 70 74 6b 3d 22 41 64 62 /" x:xmptk="Adob
00000100: 65 20 58 4d 50 20 43 72 65 20 35 2e 30 2d 63 e XMP Core 5.0-c
00000110: 30 36 31 20 36 34 2e 31 34 30 39 34 39 2c 20 32 061 64.140949, 2
00000120: 30 31 30 31 32 30 37 2d 31 30 3a 35 37 3a 010/12/07-10:57:
盡管@CodeGnome是正確的,並且這可能屬於Code Review SE ,但無論如何您都可以在這里進行:
將多個
sed
命令組合成一個命令的效率
sed
,例如:
sed -n -e 's/^<pre>//' -e '/00000000:/,$p'
我決定撤回這部分,因為我不確定這是更好還是更清晰。 您的版本很好,除了s/^<pre>//
比s/^.....//
更好。
檢查參數數量以指示錯誤時,請使用exit 1
for file in *.
是什么for file in *.
那里? 迭代所有以點結尾的文件嗎? 錯字?
除非您100%確定文件名將永遠不包含空格,否則應使用引號,但不要在不需要的地方引號,例如:
filename=$(basename "$file") # need to quote extension=${filename##*.} # no need, filename=${filename%.*} # no need sed ... "$file" # need to quote ... | xxd > "$filename".jpg # need to quote
最后一個awk
可能更短,並且循環出錯的可能性更低:
... | awk '{printf $2; for (i=3; i<=17; ++i) printf " " $i; print ""}'
看來您想學習。 您可能也對另一個答案感興趣: 編寫健壯的Shell腳本的規則是什么?
錯誤消息應該發送到stderr,不要硬編碼腳本的名稱,以防日后重命名,並且應該以非零值退出。
if (( ! $# )); then
echo >&2 "Run script as '$0' \$extension"
exit 1
fi
如果你打算把then
在同一行if
,那么你就應該把do
在同一行for
,也為一致性:
for file in *.$1; do
使用file
作為全名,使用filename
作為基本filename
會使變量名選擇混亂。 我將使用basename
作為變量,以匹配操作。 並且您需要引用參數擴展:
basename=$(basename "$file")
但是,您無需引用作業的右側:
extension=${basename##*.}
文件名中不帶擴展名的部分有時稱為root
(在vi和csh :
-modifiers中,您可以通過:r
獲得它)...使用該名稱比更改現有變量並重新使用它更容易混淆:
root=${basename%.*}
至於實際的管道,我將對其重新排序以將head
放在awk
之前,因為sed
和head
都是關於要打印的行,並且應該在修改這些選定行的awk
之前分組在一起。 我還將使用循環和printf
使awk
更加靈活:
sed -n '/0\{8\}:/,$p' "$file" |
head -n -3 |
awk '{ printf "%s", $2; for (f=3;f<=17;++f) { printf " %s", $f }; print "" }' |
xxd -p -r > "$root.jpg"
done
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.