簡體   English   中英

grep多列,順序還是awk更好?

[英]grep multi column, in order or awk better?

Linux Debian測試64。

我希望grep或awk以下內容...

ExifListAll =(下面)

DSCF3566.JPG    2014-07-21 12:54:32 On  1
DSCF3566.RAF    2014-07-21 12:54:32 On  1
DSCF3567.JPG    2014-07-21 12:54:33 On  2
DSCF3567.RAF    2014-07-21 12:54:33 On  2
DSCF3568.JPG    2014-07-21 12:54:33 On  3
DSCF3568.RAF    2014-07-21 12:54:33 On  3
DSCF3569.JPG    2014-07-21 12:54:34 Off 0

我將使用第3列時間12:54:33開始,搜索1秒鍾之前和之后的1秒鍾,第4列=“打開”,第5列= 1、2或3

到目前為止,我已經嘗試過了;

echo "$ExifListAll" | grep -E '2014-07-21.*12:45:3[3-4].*On.*[1-3]'

我可以更有效地使用awk 1襯板嗎?

我這樣做正確嗎?

echo "$ExifListAll" | awk '$4 == "On" && $5~/1/,$5~/3/'

謝謝。

grep可以正常工作。 您只是在語法上遇到了挑戰。 首先,更容易使用模式\\s*來匹配字段之間的零個或多個空格。 您正在使用.* (因為正則表達式很貪婪),它將使每個字符都匹配到該行的末尾。 同樣,字符類是指其中包含的字符。 即匹配1、2或3,請使用[123] 通過這些更改,以下內容可以實現您的意圖:

echo "$ExifListAll" | grep -E "2014-07-21\s*12:54:3[34]\s*On\s*[123]"

輸出:

$ cat grepdat.dat | grep -E "2014-07-21\s*12:54:3[34]\s*On\s*[123]"
DSCF3567.JPG    2014-07-21 12:54:33 On  2
DSCF3567.RAF    2014-07-21 12:54:33 On  2
DSCF3568.JPG    2014-07-21 12:54:33 On  3
DSCF3568.RAF    2014-07-21 12:54:33 On  3

這不是您期望的輸出嗎? 12:54:34的Off0 ,我從您的問題中解釋為不想要。 如果您希望狀態為On/Off regardless, and included the對應於12:54:34關0的0`,請使用:

echo "$ExifListAll" | grep -E "2014-07-21\s*12:54:3[34]\s*(On|Off)\s*[0123]"

輸出:

$ cat grepdat.dat | grep -E "2014-07-21\s*12:54:3[34]\s*(On|Off)\s*[0123]"
DSCF3567.JPG    2014-07-21 12:54:33 On  2
DSCF3567.RAF    2014-07-21 12:54:33 On  2
DSCF3568.JPG    2014-07-21 12:54:33 On  3
DSCF3568.RAF    2014-07-21 12:54:33 On  3
DSCF3569.JPG    2014-07-21 12:54:34 Off 0

每個注釋都需要1-6行:

cat grepdat.dat | grep -E "2014-07-21\s*12:54:3[234]\s*On\s*[123]"

產量

$ cat grepdat.dat | grep -E "2014-07-21\s*12:54:3[234]\s*On\s*[123]"
DSCF3566.JPG    2014-07-21 12:54:32 On  1
DSCF3566.RAF    2014-07-21 12:54:32 On  1
DSCF3567.JPG    2014-07-21 12:54:33 On  2
DSCF3567.RAF    2014-07-21 12:54:33 On  2
DSCF3568.JPG    2014-07-21 12:54:33 On  3
DSCF3568.RAF    2014-07-21 12:54:33 On  3

您不能使用范圍或標志來檢索多個與/ end /塊匹配的行。 對於使用awk的更通用的解決方案,您可以將時間轉換為紀元時間,然后進行比較:

mydatetime="2014-07-21 12:54:33"
awk -v expected_time=$(date -d"$mydatetime" +%s) '
  { t = $2" "$3; gsub(/[:-]/," ",t); t1 = mktime(t) }
  t1 >= expected_time-1 && t1 <= expected_time+1 && $4 =="On" && $5 ~ /^[123]$/
' file.txt

注意:

  1. 第1行:使用-v Expected_time = $(...),將Expected_time設置為紀元時間戳。
  2. 將每個記錄的條目時間($ 2“” $ 3)轉換為格式“ YYYY mm dd HH MM SS”,然后輸入mktime()以生成帶有awk的紀元時間戳。
  3. 比較時間並確保$ 4為“開”,並且$ 5為1、2或3。

如果您確切地知道了您所提到的Expected_time,那么只使用grep行,它比awk行更簡單,更快。

grep -E '2014-07-21.*12:54:3[2-4].*On.*[1-3]' file.txt

謝謝大家的建議。

我已經使用了另一種更直接的方法,即'exiftool',它從圖像中讀取所有元數據。

我選擇了目錄中的任何圖像,然后給出前一秒和下一秒。 我不確定如何替換所提供的信息,但是我會在您的幫助下進行整理。

DateTimeOrigFirst="$(exiftool -T -d '%F %T' -DateTimeOriginal DSCF3567.RAF)"
DateTimeOrig1SecMinus="$(exiftool -T -globalTimeShift "-0:0:0 0:0:1" -d '%F %T' -DateTimeOriginal DSCF3567.RAF)"
DateTimeOrig1SecPlus="$(exiftool -T -globalTimeShift "+0:0:0 0:0:1" -d '%F %T' -DateTimeOriginal DSCF3567.RAF)"

然后,我可以在第一個示例中使用1-6生成圖像1-6;

printf %s\\n "$ExifListAll" | tr '\t' ' ' | grep \
-E "$DateTimeOrigFirst|$DateTimeOrig1SecMinus|$DateTimeOrig1SecPlus"

再次感謝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM