我尝试检查字符串的第一个或最后一个字符是否是x
,但却收到一条错误消息:
./test.sh:2:错误替换
这里有什么问题?
string="2x3"
if [[ "${-n $string | head -c 1}" == "x" ]]; then
echo "first character is x"
elif [[ "${-n $string | tail -c 1}" == "x" ]]; then
echo "last character is x"
fi
我尝试检查字符串的第一个或最后一个字符是否是x
,但却收到一条错误消息:
./test.sh:2:错误替换
这里有什么问题?
string="2x3"
if [[ "${-n $string | head -c 1}" == "x" ]]; then
echo "first character is x"
elif [[ "${-n $string | tail -c 1}" == "x" ]]; then
echo "last character is x"
fi
macOS 14.5,Zsh 5.9。
ls -A -- ~/
:
.zshrc
system-wide-clipboard.zsh
cat -- ~/.zshrc
:
autoload -Uz zmv
alias zcp='zmv -C'
alias zln='zmv -L'
. ./system-wide-clipboard.zsh
例如,如果我在 中打开终端应用程序,Zsh 会尝试在 中~/test/
查找,而不是在 中查找。system-wide-clipboard.zsh
~/test/
~/
如何解决这个问题?
(我自己尝试过用. ./system-wide-clipboard.zsh
、. system-wide-clipboard.zsh
或source ./system-wide-clipboard.zsh
替换source system-wide-clipboard.zsh
,但这没有帮助。)
要执行随机 shell 脚本(例如,script.sh
仅包含一行)echo 'foo'
,我可以使用zsh script.sh
,并且这样可以正常工作。但是,如果我尝试使用点语法(即)执行同一文件,则会./script.sh
出现错误:zsh: permission denied: ./script.sh
,即使我#!/bin/zsh
在文件的最开头添加了。这是为什么?
有人能解释一下为什么
ffmpeg -i input.mov -ss 00:00:10 -to 00:00:15 output1.mov
制作一段 5 秒的视频,从第 10 秒到第 15 秒,而
ffmpeg -ss 00:00:10 -i input.mov -to 00:00:15 output2.mov
制作一个15秒的视频,从第10秒到第25秒?
我尝试弄清楚如何使用ddjvu
将 DjVu 文件转换为 PDF。如果我使用
ddjvu -format=pdf input.djvu output.pdf
输出的 PDF 非常大,并且由无损图像组成。此外,还会出现一个警告,我稍后会谈到:
TIFFWriteDirectorySec:警告,使用旧版 Deflate 编解码器标识符创建 TIFF,COMPRESSION_ADOBE_DEFLATE 受到更广泛的支持。
为了使输出文件更小并且由有损图像组成,man ddjvu
建议使用以下-quality
选项:
-quality=factor:为 TIFF 和 PDF 文件启用有损 JPEG 压缩。此选项仅影响无法使用首选 TIFF/G4 压缩进行编码的图像。参数因子是范围从 25 到 150 的量化因子。有关 JPEG 量化因子的更多信息,请参阅命令 cjpeg(1)。值 80 是一个很好的起点。
如果我使用的值不超过 100(例如 80、90 或 100),
ddjvu -format=pdf -quality 90 input.djvu output.pdf
TIFFWriteDirectorySec 警告不会出现。据我了解,这是因为使用-quality
意味着 PDF 将由有损图像组成,这反过来意味着它将由 JPEG 而不是 TIFF 组成。
但是如果值高于 100,例如 105 或 150,警告会再次出现。这是为什么?
使用 ddjvu 转换为 PDF 时:
ddjvu -format=pdf input.djvu output.pdf
有一个警告:
TIFFWriteDirectorySec:警告,使用旧版 Deflate 编解码器标识符创建 TIFF,COMPRESSION_ADOBE_DEFLATE 受到更广泛的支持。
如何使用 COMPRESSION_ADOBE_DEFLATE 而不是 delfate?
我试过
ddjvu -format=pdf -quality=COMPRESSION_ADOBE_DEFLATE input.djvu output.pdf
但虽然-quality=deflate
有效,-quality=COMPRESSION_ADOBE_DEFLATE
并且其变体(例如AdobeDeflate
)却返回错误消息:
ddjvu:选项“-quality”的有效参数是 25 到 150 之间的整数。
要将 PostScript 文件转换为 PDF,我可以使用
ps2pdf input.ps output.pdf
ps2pdfwr input.ps output.pdf
但两者之间真正的实际区别是什么?我知道在命令行中ps2pdf
提供了开关,而描述了它的用法,即在不指定 CompatibilityLevel 的情况下将 PostScript 转换为 PDF。-dCompatibility=1.x
man ps2pdfwr
但这是否意味着它们之间唯一的真正区别是前者提供切换功能-dCompatibility
,而后者不提供呢?我认为答案是“不”(因为在这种情况下开发后者的实用功能将是一个相当愚蠢的想法),这就是为什么我希望有人能向我解释两者之间的所有实际区别以及优点/缺点/陷阱。
ddjvu(DjVuLibre),3.5.28:
ddjvu --help
返回
-format=FMT Select output format: pbm,pgm,ppm,pnm,rle,tiff.
请注意,它没有提到 PDF。但是,为什么下面的命令可以工作并将输入 DjVu 文件转换为输出 PDF 文件呢?
ddjvu -format=pdf -quality=85 input.djvu output.pdf
在记录命令行内容时,通常需要使用通用名称。
有时我使用input
andoutput
词语,它们发挥得很好:
# example 1
pandoc input_file.md -o output_file.htm
但有时它们表现得不太好,我用source
andtarget
代替:
# example 2
mv source_file.txt target_folder/
我在这里有两个问题。
source
第一个问题是仅使用和target
配对是否可以(从英语(对我来说是外语)、逻辑等方面来看) ?说“then input
and”这对词更通用,这样说是否正确output
?
target
第二个问题是不用的时候用好不好source
?例如:
# example 3. ImageMagick will copy all the .jpg and .png files
# to target_folder, and then trim them there
magick mogrify -path target_folder/ -trim +repage *.(jpg|png)
这是 Terdon 建议的一种将文件重命名为随机文件名的方法。这种方法的优点是它可以自动解决文件名冲突:
randomname() { base64 < /dev/urandom | tr -dC a-z0-9 | head -c4; }
for f in *.png; do
newName=$(randomname).png
while [ -e "$newName" ]; do
newName=$(randomname).png
done
mv -- "$f" "$newName"
done
这是另一种方法,使用zmv
.优点是可以用它批量重命名不同扩展名的文件:
zmv '*(.*)' '${(Lr:8:)$(uuidgen)}$1'
我想修改第二种方法,以便它能够像第一种方法一样自动解析文件名冲突,但我不明白如何实现。有人可以帮忙吗?
有一个 Zsh 变量,其内容如下:
$if(description-meta)$
<meta name="description" content="$description-meta$" />
$endif$
<title>$if(title-prefix)$$title-prefix$ – $endif$$pagetitle$</title>
<style>
$styles.html()$
</style>
$for(css)$
<link rel="stylesheet" href="$css$" />
$endfor$
我需要删除 <title>
这一行,即:
<title>$if(title-prefix)$$title-prefix$ – $endif$$pagetitle$</title>
并覆盖该变量或创建一个新变量,使其变为:
$if(description-meta)$
<meta name="description" content="$description-meta$" />
$endif$
<style>
$styles.html()$
</style>
$for(css)$
<link rel="stylesheet" href="$css$" />
$endfor$
如何使用 awk
或 sed
来实现?
该命令用于使用以下命令重命名文件uuidgen
:
zmv '(*)(.*)' '`uuidgen | head -c 8`$2'
有人可以展示如何将结果字符串转换为小写吗?
有时我需要将文件批量重命名为随机或伪随机文件名,仅八个小写字母和数字,例如从mcmurdo-station.png
到类似a12bc0xy.png
. 为此,我使用 CRC32:
for f in *.png; do mv $f $(crc32 $f); done
但有一个缺点,如果同一个文件夹中有两个相同的文件,它们具有相同的校验和,因此会出现文件名冲突。当然,通常我不会将相同的文件存储在同一个文件夹中,但我仍然希望在批量重命名时避免这种过度自动化。
我在互联网上找到的另一种方法是使用base64:
foo % randomname() { head -c8 /dev/urandom | base64 | tr -dc a-z0-9; }
zmv '(*).(*)' '`randomname`.$2'
但生成的文件名长度不同:第一个测试文件从foo.png
to重命名52rud.png
,而第二个测试文件从bar.png
to 重命名pxg.png
。
还有一个使用shuf
GNU Core Utils 的解决方案:https://unix.stackexchange.com/a/259761,但现在我更愿意找到一种不需要安装第三方软件包的方法。
什么是好的且简单的替代方案?
根据man cp
,使用cp -P * foo/
意味着不会遵循任何符号链接:
-P
:不遵循任何符号链接。-R
如果指定了该选项,则这是默认值。
但是如何以相同的方式复制文件,即不遵循符号链接,使用 Zsh glob 限定符而不使用-P
?我需要使用cp *(.) foo/
还是需要cp *(-.) foo/
替代使用?
Bash 和 Zsh 之间有什么实际区别?关于询问不同:
foo*(.)
:仅匹配常规文件foo*
以及到常规文件的符号链接,而不是目录和其他特殊文件。foo*(-.)
:仅匹配常规文件foo*
,不匹配符号链接和其他特殊文件。
似乎答案是foo*(-.)
,但我不确定,我真的很想弄清楚这些事情。
zsh 5.9 (x86_64-apple-darwin23.0)
使用 时,使用[0-9]
或代替<->
匹配数字是否有任何区别(实用或不实用) zmv
?
例如,我尝试了以下两个命令,它们的工作原理似乎相同。任一者将所有文件(例如foo1.jpg
或 )复制bar0053.png
到images
目录中。
zmv '*<->.(gif|jpg|png)' 'images/'
zmv '*[0-9].(gif|jpg|png)' 'images/'
使用 glob 限定符搜索时如何排除一个或多个文件名后缀?
工作正常,这里我们匹配文件名后缀,而不是排除它们:
print -rC1 **/*.(txt)(.)
print -rC1 **/*.(jpg|png)(.)
我们并不是试图排除它们,但行不通:
print -rC1 **/*.(^txt)(.)
print -rC1 **/*.(^jpg|^png)(.)
zsh 5.9 (x86_64-apple-darwin23.0)
这是zmv
用一个下划线非递归地替换任意数量的空格的命令(感谢 Stéphane Chazelas,他帮助了我):
zmv -- '* *' '${f// ##/_}'
这是来自互联网的命令,它似乎做同样的事情,但是递归地:
zmv -- '(**/)(* *)' '$1${2//( #-## #| ##)/_}'
有人可以解释它是如何工作的吗?具体来说,该( #-## #| ##)
部分如何工作?
如何使用zmv
, 将任意数量的空格替换为单个下划线?
我目前使用的是
zmv -- '* *' '$f:gs/ /_'
但它取代了每个空格,因此foo bar.txt
变成foo___bar.txt
, not foo_bar.txt
(我希望它是)。
我尝试了解如何将 Zsh glob 限定符与ls
.
互联网上的一篇文章说,要将文件从最大到最小排序,我可以使用ls *(oL)
.
o<sort>
- 根据值对文件进行排序<sort>
O<sort>
- 类似o
,但按降序排列的值
<sort>
可以是:
n
- 按名称排序(默认)。L
- 按大小排序。l
- 按链接数量排序。a
- 按上次访问排序。m
- 按最后修改排序。c
- 按上次 inode 更改排序。d
- 子目录中的文件出现在前面。N
- 不要排序任何东西。例如:
# Sort files from the smallest to the largest ls *(oL)
但ls *(oL)
不会以这种方式列出文件,ls *(On)
不会按相反的字母顺序列出文件,ls *(om)
不会按修改日期对文件进行排序(如果运行,则没有区别ls *(Om)
)。所有命令都按常规字母顺序(从 A 到 Z)列出文件,仅此而已。似乎ls
忽略了 Zsh 全局变量?
我应该说,在其他情况下,Zsh glob 似乎对我来说工作正常。例如,print -rC1 *(.)
仅打印文件,不打印目录。
zsh 5.9 (x86_64-apple-darwin23.0)
来自man cp
,删节:
-a
:存档模式。与选项相同-RpP
。保留文件的结构和属性,但不保留目录结构。-R
:如果source_file
指定一个目录,cp
则复制该目录和该点连接的整个子树。如果source_file
以 a 结尾/
,则复制目录的内容而不是目录本身。-p
:导致cp
在副本中保留每个源文件的以下属性:修改时间、访问时间、文件标志、文件模式、用户 ID 和组 ID(如权限所允许)。-P
:不遵循任何符号链接。-R
如果指定了该选项,则这是默认值。
-P
被描述为包含在-R
,但是为什么-a
被描述为-RpP
而不是仅仅-Rp
?-a
不保留目录结构是什么意思?-R
复制文件时,和标志是否-P
有意义,而不是文件夹,例如,在执行 时cp *.(txt|md) docs/
?zsh 5.9(x86_64-apple-darwin23.0),macOS 14.4.1