是否有一个 Linux 脚本/应用程序,而不是删除文件,而是将它们移动到一个特殊的“垃圾”位置?我想用它来代替rm(甚至可能是后者的别名;这样做有利有弊)。
“垃圾”是指一个特殊的文件夹。单个mv $* ~/.trash是第一步,但理想情况下,这还应该处理多个同名文件的垃圾处理,而不会覆盖旧的垃圾文件,并允许使用简单的命令(一种“撤消”)将文件恢复到其原始位置。此外,如果在重新启动时自动清空垃圾(或防止无休止增长的类似机制),那就太好了。
存在针对此问题的部分解决方案,但“恢复”操作尤其重要。是否有任何现有的解决方案不依赖图形外壳中的垃圾系统?
(顺便说一句,这种方法是否合理,而不是使用频繁的备份和 VCS 是否合理,一直存在无休止的讨论。虽然这些讨论有一定的意义,但我相信我的要求仍然存在。)
标准cat逐行连接文件(逐行,如果你愿意的话)。我发现自己最近越来越需要水平 cat命令;即一个命令,它接受一个文件列表并将它们水平连接起来,逐列。到目前为止,我已经使用了临时解决方法,但我想知道是否存在一个很好的解决方案。
为了澄清,请考虑以下两个文件之间cat和hcat的比较:
$ cat a.dat 1.dat
a b
c d
1 2
3 4
$ hcat -s ' ' a.dat 1.dat
a b 1 2
c d 3 4
Run Code Online (Sandbox Code Playgroud)
(与cat我们需要指定分隔符不同,因为按照惯例,UNIX 文件的末尾没有列分隔符。)
我想在 Bash 中实现一个函数,它在每次调用时增加(并返回)一个计数。不幸的是,这似乎很重要,因为我在子 shell 中调用该函数,因此它无法修改其父 shell 的变量。
这是我的尝试:
PS_COUNT=0
ps_count_inc() {
let PS_COUNT=PS_COUNT+1
echo $PS_COUNT
}
ps_count_reset() {
let PS_COUNT=0
}
Run Code Online (Sandbox Code Playgroud)
这将按如下方式使用(因此我需要从子shell调用函数):
PS1='$(ps_count_reset)> '
PS2='$(ps_count_inc) '
Run Code Online (Sandbox Code Playgroud)
这样,我就会有一个带编号的多行提示:
> echo 'this
1 is
2 a
3 test'
Run Code Online (Sandbox Code Playgroud)
可爱的。但由于上述限制不起作用。
一个无效的解决方案是将计数写入文件而不是变量。但是,这会在多个同时运行的会话之间产生冲突。当然,我可以将 shell 的进程 ID 附加到文件名。但我希望有一个更好的解决方案,不会让我的系统因大量文件而混乱。
我正在尝试使用sed打印所有行,直到但不包括特定模式。我不明白为什么以下不起作用:
sed '/PATTERN/{d;q}' file
Run Code Online (Sandbox Code Playgroud)
根据我对 sed 脚本的理解,这个表达式应该会导致以下情况:
/PATTERN/,执行由命令组成的组
d删除模式空间(=当前行)q打印当前模式空间后的 uit孤立地,既/PATTERN/d和/PATTERN/q工作;也就是说,d删除有问题的行,并q导致sed终止,但在打印行之后,如文档所述。但是将这两个操作组合在一个块中似乎会导致q被忽略。
我知道我可以使用Q而不是{d;q}作为 GNU 扩展(这按预期工作!)但我有兴趣了解为什么上述不起作用,以及我以何种方式误解了文档。
我的实际用例(只是稍微)更复杂,因为文件的第一行实际上与模式匹配,我跳过它(在做了一些替换之后):
sed -e '1{s/>21/>chr21/; n}' -e '/>/{d;q}' in.fasta >out.fasta
Run Code Online (Sandbox Code Playgroud)
但是上面的简化案例表现出相同的行为。
我有以下功能:
bar() { echo $1:$2; }
Run Code Online (Sandbox Code Playgroud)
我正在从另一个函数调用这个函数,foo. foo本身被称为如下:
foo "This is" a test
Run Code Online (Sandbox Code Playgroud)
我想获得以下输出:
This is:a
Run Code Online (Sandbox Code Playgroud)
也就是说,bar接收到的参数应该与我传入的标记相同foo。
foo需要如何实施才能实现这一目标?我尝试了以下两种实现,但都不起作用:
foo() { bar $*; }
- 输出: this:is
foo() { bar "$*"; }
- 输出: this is a test:
我的问题是如何有效地保留参数的引用。这可能吗?
我想创建一个多行文本的表格显示,类似于以下内容:
all Build all targets
document Create documentation of source files in the subfolders
`src` and `script`, and write it to `man`
test Run unit tests
Run Code Online (Sandbox Code Playgroud)
目前,我对此的输入如下所示,但这当然可以更改:
all---Build all targets
document---Create documentation of source files in the subfolders `src` and `script`, and write it to `man`
test---Run unit tests
Run Code Online (Sandbox Code Playgroud)
我已经尝试通过awk和wrap/的组合来实现这一点,pr但是虽然换行有效,但缩进却没有。这是我目前的方法:
…
| awk -F '---' "{ printf '%-10s %s\n', $1, $2 }" \
| fold -w $(($COLUMNS - 1)) -s
Run Code Online (Sandbox Code Playgroud)
它生成输出
all Build …Run Code Online (Sandbox Code Playgroud) 我可以通过paste如下方式从单列输入创建一个包含多列的文件:
some_command | paste - -
Run Code Online (Sandbox Code Playgroud)
这some_command在以列主要格式生成数据时有效。换句话说,输入
1
2
3
4
Run Code Online (Sandbox Code Playgroud)
结果在输出
1 2
3 4
Run Code Online (Sandbox Code Playgroud)
但是,我想要相反的,即我想要
1 3
2 4
Run Code Online (Sandbox Code Playgroud)
背景:我想将M 个文件中的所有第N列收集到一个聚合文件中。我尝试通过以下方式执行此操作:
cut -f 5 "${files[@]}" | paste - - - - - …
Run Code Online (Sandbox Code Playgroud)
(与M -秒)。但如前所述,这不起作用,正如paste预期的列主要输入。我不禁认为应该有一个 coreutils(或纯 Bash)解决方案。
我需要将文件名数组传递给命令,并保留正确的引用。到目前为止,一切都很好。不幸的是,该命令实际上是一个子命令,又被另一个命令调用。具体来说,命令是:
\n\ngit filter-branch --index-filter \\\n \'git rm -rf --cached \xe2\x80\xb9file1\xe2\x80\xba \xe2\x80\xb9file2\xe2\x80\xba\xe2\x80\xa6\' \\\n HEAD\nRun Code Online (Sandbox Code Playgroud)\n\n为简单起见,我\xe2\x80\x99m 将在下面用一个显示相同问题的更简单的命令替换它:
\n\nprintf \'%s\\n\' \'cmd file1 file2\xe2\x80\xa6\'\nRun Code Online (Sandbox Code Playgroud)\n\n现在我\xe2\x80\x99已经得到了一个数组files=(\'a b\' c)。我想要的结果是上面的命令在一行中打印,并cmd根据需要单独引用后面的每个标记(例如,当存在\xe2\x80\x99s 空格时)。
如果我手动扩展并引用文件名,它会起作用:
\n\n$ printf \'%s\\n\' \'cmd \'\\\'\'a b\'\\\'\' c\'\n\xe2\x86\x92 cmd \'a b\' c\nRun Code Online (Sandbox Code Playgroud)\n\n(或者,我可以混合使用单引号和双引号来达到相同的结果。)
\n\n但如果我尝试传递数组,它就不再起作用:
\n\n$ (set -x; printf \'%s\\n\' "cmd \'${files[@]}\'")\n+ printf \'%s\\n\' \'cmd \'\\\'\'a b\' \'c\'\\\'\'\'\n\xe2\x86\x92 cmd \'a b\nc\'\nRun Code Online (Sandbox Code Playgroud)$ (set -x; printf \'%s\\n\' \'cmd \'\\\'"${files[@]}"\\\')\n+ printf \'%s\\n\' …Run Code Online (Sandbox Code Playgroud)我有大约以下代码:
cat infile | while read line; do
echo 2> 'log ' $line
echo $line
done > outfile
Run Code Online (Sandbox Code Playgroud)
outfile已正确创建。但是,STDERR 输出刚刚消失:它既没有显示在终端上,也没有显示在outfile. 如果我用done > outfile 2> errfilethen替换上面的最后一行,则errfile创建,但为空。
我可以从循环内捕获错误输出吗,最好是通过将其直接流式传输到父 STDERR 中(以上是较大脚本的一部分,其标准错误流由另一个进程捕获)?