所以我需要的确切。 我有一个文件,我逐行循环,当我发现单词"搜索"我需要在前一行返回并更改单词" false"到"真"在那一行内,但只在那一行而不是所有文件。我是bash的新手以及我所拥有的一切。
backupIndex
答案 0 :(得分:4)
你可以用纯粹的bash做这件事:
# Declare a function process_file doing the stuff
process_file() {
# Always have the previous line ready, hold off printing
# until we know if it needs to be changed.
read prev
while read line; do
if [[ $line == *"[search]"* ]]; then
# substitute false with true in $prev. Use ${prev//false/true} if
# several occurrences may need to be replaced.
echo "${prev/false/true}"
else
echo "$prev"
fi
# remember current line as previous for next turn
prev="$line"
done
# in the end, print the last line (it was saved as $prev) in the last
# loop iteration.
echo "$prev"
}
# call function, feed file to it.
process_file < file
但是,有些工具比纯bash更适合这种文件处理,并且常用于shell脚本:awk
和sed
。这些工具通过逐行读取 1 来处理文件,并分别为每一行运行一段代码,保留行之间的某些状态(与上面的代码不同),并提供更强大的文本处理功能设施。
为此,我使用awk
:
awk 'index($0, "[search]") { sub(/false/, "true", prev) } NR != 1 { print prev } { prev = $0 } END { print prev }' filename
那是:
index($0, "[search]") { # if the currently processed line contains
sub(/false/, "true", prev) # "[search]", replace false with true in the
# saved previous line. (use gsub if more than
# one occurrence may have to be replaced)
}
NR != 1 { # then, unless we're processing the first line
# and don't have a previous line,
print prev # print the previous line
}
{ # then, for all lines:
prev = $0 # remember it as previous line for the next turn
}
END { # and after the last line was processed,
print prev # print the last line (that we just saved
# as prev)
}
您也可以使用sed
:
sed '/\[search\]/ { x; s/false/true/; x; }; x; ${ p; x; }; 1d' filename
...但正如你所看到的,sed有点神秘。它有自己的优势,但这个问题对他们没有影响。
附录,根据要求:最重要的是要知道sed
读取的内容称为模式空间(大多数命令在其上运行)并且侧面有一个保持缓冲区你可以在线之间保存东西。我们将使用保持缓冲区来保存当前的前一行。代码的工作原理如下:
/\[search\]/ { # if the currently processed line contains [search]
x # eXchange pattern space (PS) and hold buffer (HB)
s/false/true/ # replace false with true in the pattern space
x # swap back. This changed false to true in the PS.
# Use s/false/true/g for multiple occurrences.
}
x # swap pattern space, hold buffer (the previous line
# is now in the PS, the current in the HB)
${ # if we're processing the last line,
p # print the PS
x # swap again (current line is now in PS)
}
1d # If we're processing the first line, the PS now holds
# the empty line that was originally in the HB. Don't
# print that.
# We're dropping off the end here, and since we didn't
# disable auto-print, the PS will be printed now.
# That is the previous line except if we're processing
# the last line (then it's the last line)
好吧,我确实警告过你sed
比awk更隐秘。这段代码的一个警告是它希望输入文件有多行。
1 在awk
的情况下,它的记录不必是行,而是默认的行。
答案 1 :(得分:1)
一种非常简单的方法是一次读取2行,然后检查第二行中的条件并替换上一行。
while read prev_line # reads every 1st line
do
read curr_line # reads every 2nd line
if [[ $curr_line == *"[search]"* ]]; then
echo "${prev_line/false/true}"
echo "$curr_line
else
echo "$prev_line"
echo "$curr_line"
fi
done < "file.txt"
答案 2 :(得分:0)
你这样做的正确版本是:
groupingView: {
...
formatDisplayField: [
function (displayValue) { //, value, cm, index, grp) {
return String(displayValue).substring(0, 5);
}
],
isInTheSameGroup: function (x, y) {
return String(x).substring(0, 5) === String(y).substring(0, 5);
}
}