管道多行电源外壳在一行中生成多个参数



我正在尝试编写一个单行代码,该代码获取目录中tif文件的唯一ID,然后运行ImageMajick的转换将它们组合成多页tif:

convert ..image_dataua-nws_00000991_001.tif ..image_dataua-nws_00000991_002.tif ..image_dataua-nws_00000991_003.tif ..image_dataua-nws_00000991_004.tif ua-nws_00000991_all.tif

这有效,但我正在尝试为一堆 id 自动化它,每个 id 有几个 tif。目前,我只使用一个id并使用"echo"而不是转换:

echo "ua-nws_00000991" | % { $id=$_; ls ../image_data | ? { $_.FullName -match $id } | % { 
echo $_.FullName } | Join-String -Separator '" "' | % { echo '"'$_'"' $id"_all.tif" }
}

但是我在将文件列表转换为参数列表时遇到问题。我得到以下内容(我已经手动制作了相对于在线发布的路径):

"
.image_dataua-nws_00000991_001.tif" ".image_dataua-nws_00000991_002.tif" ".image_dataua-nws_00000991_003.tif" "C:Daniels_StuffClassesCurrentgrad_aiprojectrepoarticle-reconstructionimage_dataua-nws_00000991_004.tif"
ua-nws_00000991_all.tif

在我添加双引号之前,convert将所有最终$_解释为一个参数。我正在添加引号以强制转换将它们视为多个参数。但我似乎无法摆脱那个换行符。我认为这可能是由最终echo引起的,但是如果我将其替换为转换,我会得到以下结果:

convert.exe: unable to open module file `C:Program FilesImageMagick-6.9.2-Q16modulescodersIM_MOD_RL_ABSOLUTEPATHTOMYIMAGESIMAGE_DATAUA-NWS_00000991_001.TIF C_.dll': No such file or directory @ warning/module.c/GetMagickModulePath/674.
convert.exe: no decode delegate for this image format `ABSOLUTEPATHTOMYIMAGESIMAGE_DATAUA-NWS_00000991_001.TIF C' @ error/constitute.c/ReadImage/501.
convert.exe: no images defined `ua-nws_00000991_all.tif' @ error/convert.c/ConvertImageCommand/3241.

虽然我不理解Powershell的疯狂语法,但ImageMagick有两个方面可能会帮助你......

方面 1 - 标准上的文件名

首先,您可以在ImageMagickstdin上传递文件名列表以合并到单个 TIF 中,而不是作为参数。因此,如果您有一本书的 3 页,在 3 个文件中称为p1.tifp2.tifp3.tif,而不是 做:

convert p*.tif book.tif

你也可以做

dir /b/s p*tif | convert @- book.tif

当我使用DIR /B/S生成上述名称时,我希望您希望将其替换为您的 Powershell 命令。

看点 2 - 单个管道下达多个图像

其次,您可以使用"Magick Image File Format">(MIFF)流将来自convert多次调用的多个图像通过管道传输到convert的进一步最终调用:

下面是一个示例,其中对convert的两个调用都分别将图像发送到最终convert,该从其 MIFF 输入流中加入图像:

( convert p1.tif MIFF:- & convert p2.tif MIFF:- ) | convert MIFF:- book.tif

这是同一事物的一个略有不同的示例:

FOR files *.TIF; DO
IF this file has the correct id
convert $this MIFF:-
ENDIF
ENDDO | convert MIFF:- book.tif 

我不知道Join-String是从哪里来的,但我只能猜测它坏了——因为我看不到换行符来自哪里。

将一些测试文件放在一个文件夹中:

Name                      
----                      
ua-nws_00000991_001.tif   
ua-nws_00000991_002.tif   
ua-nws_00000991_003.tif   
ua-nws_00000991_004.tif   
ua-nws_00000992_001.tif   
ua-nws_00000992_002.tif   
ua-nws_00000992_003.tif   
ua-nws_00000992_004.tif   

Get-ChildItem(gci)列出它们,并通过从文件名中删除尾随数字来分组它们(Group-Object,又名group):

PS D:tNew folder> gci *.tif | group { $_.Name -replace '_d+.tif$' }
Count Name                      Group                                                                                                       
----- ----                      -----                                                                                                       
4 ua-nws_00000991           {D:tNew folderua-nws_00000991_001.tif, D:tNew folderua-nws_00000991_002.tif, D:tNew folderua-nws...
4 ua-nws_00000992           {D:tNew folderua-nws_00000992_001.tif, D:tNew folderua-nws_00000992_002.tif, D:tNew folderua-nws...

现在我们有组,其中组名称是映像 ID,该 ID 的文件列表是组成员。整洁。现在运行转换一次foreach(%)组,方法是将完整的文件名作为要转换的参数,并从组ID($_.name)生成一个新的文件名,末尾带有_full.tif

gci *.tif | group { $_.Name -replace '_d+.tif$' } |% { Start-Process convert -ArgumentList (@($_.group.fullname) + @("$($_.Name)_full.tif"))}

这可能无法按原样工作,我没有安装convert来尝试它,您需要调整路径。但我认为这种方法会奏效。

您可以尝试以下操作:

get-childitem "image_data" -recurse -filter ua-nws_00000991*.tif | % { convert $_.Fullname }

返回"image_data"目录中的所有 tif 文件,并为每个找到的 tif 文件调用convert

希望有帮助

最新更新