我有一个自动化流程,其中包含许多行,如下所示:
sudo cat /some/path/to/a/file >> /some/other/file
如果尚未添加/some/other/file
,我想将其转换为只附加到/some/path/to/a/file
的单行内容。
修改 很明显,我需要一些例子。
示例1:更新特定登录的.bashrc脚本
示例2:为不同的登录创建.screenrc
示例3:附加到/ etc / config文件的末尾
其他一些警告。该文本将添加到块(>>)中。因此,查看是否在文件末尾附近添加整个代码块应该相对简单。我试图想出一个简单的方法来确定文件是否已经附加到原始文件。
谢谢!
示例python脚本......
def check_for_appended(new_file, original_file):
""" Checks original_file to see if it has the contents of new_file """
new_lines = reversed(new_file.split("\n"))
original_lines = reversed(original_file.split("\n"))
appended = None
for new_line, orig_line in zip(new_lines, original_lines):
if new_line != orig_line:
appended = False
break
else:
appended = True
return appended
答案 0 :(得分:2)
也许这会让你开始 - 这个GNU awk脚本:
gawk -v RS='^$' 'NR==FNR{f1=$0;next} {print (index($0,f1) ? "present" : "absent")}' file1 file2
将告诉您“file1”中是否存在“file1”的内容。它不能告诉你为什么,例如因为您之前已将file1连接到file2的末尾。
这就是你需要的吗?如果没有更新您的问题以澄清/解释。
答案 1 :(得分:0)
使用
添加每个文件 if [ -z "$__<filename>__" ]; then __<filename>__=1; else
(当然用文件名替换<filename>
)并在最后
fi
这样,你可以在每个文件中包含脚本,并测试一次只有一次的内容。
答案 2 :(得分:0)
这是一种查看文件是否包含其他文件的技术
contains_file_in_file() {
local small=$1
local big=$2
awk -v RS="" '{small=$0; getline; exit !index($0, small)}' "$small" "$big"
}
if ! contains_file_in_file /some/path/to/a/file /some/other/file; then
sudo cat /some/path/to/a/file >> /some/other/file
fi
答案 3 :(得分:0)
这对你有用吗?
sudo (set -o noclobber; date > /tmp/testfile)
noclobber可防止覆盖现有文件。
我认为它没有,因为你写过你想要附加一些东西,但这种技术可能有所帮助。
当在一个脚本中发生追加all时,请使用标志:
if [ -z "${appended_the_file}" ]; then
cat /some/path/to/a/file >> /some/other/file
appended_the_file="Yes I have done it except for permission/right issues"
fi
我会继续写一个function appendOnce { .. }
,其中包含上述内容。如果你真的想要一个丑陋的oneliner(丑陋:眼睛和同事的痛苦):
test -z "${ugly}" && cat /some/path/to/a/file >> /some/other/file && ugly="dirt"
将此与sudo结合使用:
test -z "${ugly}" && sudo "cat /some/path/to/a/file >> /some/other/file" && ugly="dirt"
答案 4 :(得分:0)
看来你想要的是一组可以作为一个单元运行的脚本段。你的方法 - 将它们组合成一个文件 - 很难维护并受到各种竞争条件的影响,使其实现变得棘手。
一种更简单的方法,类似于大多数现代Linux发行版所使用的方法,是创建一个脚本目录,比如~/.bashrc.d
,并将每个块保存为该目录中的单个文件。
驱动程序(替换所有这些文件的串联)只是一次运行一个目录中的脚本:
if [[ -d ~/.bashrc.d ]]; then
for f in ~/.bashrc.d/*; do
if [[ -f "$f" ]]; then
source "$f"
fi
done
fi
要从骨架目录添加文件,只需创建一个新的符号链接。
add_fragment() {
if [[ -f "$FRAGMENT_SKELETON/$1" ]]; then
# The following will silently fail if the symlink already
# exists. If you wanted to report that, you could add || echo...
ln -s "$FRAGMENT_SKELETON/$1" "~/.bashrc.d/$1" 2>>/dev/null
else
echo "Not a valid fragment name: '$1'"
exit 1
fi
}
当然,可以通过内容而不是名称来有效地索引文件。但在大多数情况下,按名称编制索引会更好,因为它对编辑脚本片段很有用。如果您使用了内容检查(例如,md5sum),您将冒着使用相同片段的旧版本和新版本的风险,这两个版本都是活动的,并且没有明显的方法来删除旧版本。
但是,将上述结构适应您可能有的任何要求和限制应该是直截了当的。
例如,如果无法使用符号链接(例如,因为骨架和实例不共享文件系统),则可以复制文件。如果文件已经存在且具有相同的内容,您可能希望避免复制,但这只是为了提高效率,如果脚本片段很小,则可能不是很重要。或者,您可以使用rsync
来保持骨架和实例彼此同步;这将是一个非常可靠和低维护的解决方案。