
我有一個文件
XYZ 123 S S R O O S F
PQR 456 F S S R O F F
ABC 789 F S R S S F S
現在,在整行中,當我找到“R”&&然後是“O”或“S”時,我想獲取列號並根據列號我需要執行命令,如果為真則顯示 L 而不是 R 和 O或S 如果為false,則用F 代替R,用F 代替O(對於所有連續的O)或 S
現在從「否」欄中我將確定日期,
假設第一行 R 在 5 上,因此日期將是第 3 列,即第二列,
對於第二行日期將是 6-3 即第三行,第三行又是 5-3 即第二行,
所以我將使用變數 date=%m/d(來自第 3 列)/%Y
現在的命令是./bpimagelist -client <column 1> -policy <column 2> -hoursago 100000 -U | awk -v date="$date" '$1 == date' | wc -l
,現在如果值為 0 則為 false,如果為 gt 0 則為 true。
XYZ is false
PQR is true
ABC is true
那麼輸出應該是
XYZ 123 S S F F F S F
PQR 456 F S S L O F F
ABC 789 F S L S S F S
根據 Valentin 的說法,在做了一些修改後,這段程式碼似乎運作得很好。
while read line;
do
day="$(echo $line | awk '{for (i=1; i<=NF; i++) { if($i == "R") { print i - 2; exit} } }')"
if [[ ${#day} -lt 2 ]]; then day="0${day}"; fi
month=`date '+%m'`
year=`date '+%Y'`
date=`echo $month/$day/$year`
result=$(sudo /usr/openv/netbackup/bin/admincmd/bpimagelist -client "$(echo $line | awk '{print $1}')" -policy "$(echo $line | awk '{print $2}')" -hoursago 100000 -U | awk -v date="$date" '$1 == date' | wc -l)
if [[ $result -ne 0 ]];
then
echo $line | sed 's/ R / L /'
else
echo $line | awk '{
afterR=0;
for (i=1; i<=NF; i++){
if ($i == "R") {
$i = "F";
afterR=1;
}
if (afterR == 1 && $i == "O") {
$i = "F"
}
}
print $0
}'
fi
done < temp
然而,一個小問題是,只有當 R 後面跟著 O 時,它才應該執行這些更改,直到找到 O 之外的任何內容為止。
這意味著如果輸入檔是這樣的,它不應該執行任何更改
XYZ 123 S S R O O O O
這意味著 R 僅由 O 延續,因此無需執行任何更改,否則發現除 O 之外的任何內容都執行更改
答案1
我會盡力一步步回答您的請求。假設這裡input
是輸入檔的一行:
擷取第一個「R」字元的列號
對於以下人員來說,這是一項非常簡單的工作awk
:
awk '{for (i=1; i<=NF; i++) { if($i == "R") { print i - 3; exit} } }' < input
考慮到您如何計算日期,我假設“R”不能位於第一行(否則天數可能為 0)。
提取第一列和第二列的值
這更簡單:
awk '{print $1}' < input # for first column
awk '{print $2}' < input # for second column
建構輸出
如果命令返回True
:
sed 's/ R / L /' < input
如果命令返回False
:
awk '{
afterR=0;
for (i=1; i<=NF; i++){
if ($i == "R") {
$i = "F";
afterR=1;
}
if (afterR == 1 && $i == "O") {
$i = "F"
}
}
print $0
}' < input
把它們放在一起
儘管這是不受歡迎的,但我認為沒有辦法避免循環輸入行,因為您需要為每一行運行一個非常特定的命令。請注意,對於大文件,這可能會非常慢。包含所有這些元素的腳本會是什麼樣子:
while read line;
do
date="%m/d$(echo $line | awk '{for (i=1; i<=NF; i++) { if($i == "R") { print i - 3; exit} } }')/%Y"
result=$(./bpimagelist -client "$(echo $line | awk '{print $1}')" -policy "$(echo $line | awk '{print $2}')" -hoursago 100000 -U | awk -v date="$date" '$1 == date' | wc -l)
if [[ $result -ne 0 ]];
then
echo $line | sed 's/ R / L /'
else
echo $line | awk '{
afterR=0;
for (i=1; i<=NF; i++){
if ($i == "R") {
$i = "F";
afterR=1;
}
if (afterR == 1 && $i == "O") {
$i = "F"
}
}
print $0
}'
fi
done < myinputfile.txt