如何在不涉及zsh中的临时文件的情况下读取,修改和写入同一文件?

时间:2011-02-15 19:10:22

标签: zsh

我喜欢保持历史档案整洁。由于zsh具有出色的历史搜索功能,因此无需多次保存我重复使用的所有命令(例如,finger,pwd,ls等)。要删除所有重复行的历史文件,我做了sort .zhistory|uniq -du。现在,我想把它写回同一个文件,所以如果我只是将它放在我的.zshrc中,每次登录时,我的历史记录都会被修剪和清理。如果我尝试sort .zhistory|uniq -du>.zhistory,结果文件为空!另一方面,如果我sort .zhistory|uniq -du>tempfile,它会正确地写入tempfile。知道如何写入同一个文件吗?

3 个答案:

答案 0 :(得分:2)

您可以使用变量:

file='.zhistory' && var=$(sort -u "$file") && echo "$var" > "$file"

您无法写入同一文件的原因是redirection首先出现并在实用程序看到之前截断文件。

您可以首先防止重复的行。将setopt与以下一项或多项设置一起使用(来自man zshoptions):

  

HIST_EXPIRE_DUPS_FIRST
                如果需要修剪内部历史记录以添加当前值                 命令行,设置此选项将导致最旧的历史记录                 在丢失唯一身份之前有重复丢失的事件                 列表中的事件。你应该确保设置值                 HISTSIZE比SAVEHIST更大的数字才能给你                 复制事件的一些空间,否则此选项将                 一旦历史填满,表现就像HIST_IGNORE_ALL_DUPS                 与独特的事件。

     

HIST_FIND_NO_DUPS
                在行编辑器中搜索历史条目时,请不要这样做                 显示先前找到的行的重复项,即使是                 重复不是连续的。

     

HIST_IGNORE_ALL_DUPS
                如果添加到历史记录列表的新命令行重复                 较旧的命令,从列表中删除旧命令(甚至                 如果不是之前的事件。)

     

HIST_IGNORE_DUPS(-h)
                如果是,请不要在历史列表中输入命令行                 上一次活动的重复。

     

HIST_SAVE_NO_DUPS
                写出历史文件时,重复的旧命令                 较新的那些被省略。

答案 1 :(得分:2)

程序海绵可以在您阅读的同一文件中回写。

(为了这个例子,你不知道sed -i)

echo "say what again" > file
sed s/what/woot/ file > file

太糟糕了,文件现在是空的,你丢失了文件。

echo "say what again" > file
sed s/what/woot/ file | sponge file

做你想做的事

(小心sponge > file或文件将再次为空。)

答案 2 :(得分:1)

我对这个问题没有答案的事实让我感到非常恼火,因为我写了一篇 - 在现场调用并将其完全放在你的路上:

#! /bin/bash

BACKUP_EXT=
while getopts "b:" flag
do
    case "$flag" in
        b) BACKUP_EXT="$OPTARG" ;;
    esac
done
shift $((OPTIND - 1))

CMD="$1"
shift

for filename in "$@"
do
    TMP_FILE="$(mktemp -t)"
    bash -c "$CMD" <"$filename" >"$TMP_FILE"
    if [[ -n "$BACKUP_EXT" ]]
    then
        mv "$filename" "$filename.$BACKUP_EXT"
    fi
    mv "$TMP_FILE" "$filename"
done

您现在可以说:

inplace 'sort | uniq -du' .zhistory

顺便提一下,有一种方法可以在不必排序的情况下进行统一 - 但这是另一个问题的答案!