Alguém poderia argumentar que isso não é uma linha única, mas deve funcionar em qualquer caso ("deveria", significando que eu não testei, mas o script deveria estar certo):
Get-ChildItem -Recurse | Where-Object {(Select-String -InputObject $_ -Pattern 'dummy' -Quiet) -eq $true} | ForEach-Object {Write-Output $_; Get-Content $_}
Expandido, com comentários:
# Get a listing of all files within this folder and its subfolders.
Get-ChildItem -Recurse |
# Filter files according to a script.
Where-Object {
# Pick only the files that contain the string 'dummy'.
# Note: The -Quiet parameter tells Select-String to only return a Boolean. This is preferred if you just need to use Select-String as part of a filter, and don't need the output.
(Select-String -InputObject $_ -Pattern 'dummy' -Quiet) -eq $true
} |
# Run commands against each object found.
ForEach-Object {
# Output the file properties.
Write-Output $_;
# Output the file's contents.
Get-Content $_
}
E aqui está uma versão "golfada", se você realmente quiser curta. Isso definitivamente se aproxima da qualificação como "one-liner".
ls -R|?{$_|Select-String 'dummy'}|%{$_;gc $_}
Além do uso óbvio de aliases, do recolhimento de espaços em branco e do truncamento de nomes de parâmetros, convém observar as seguintes diferenças significativas entre as versões "completa" e a versão "golfed":
-
Select-String
foi trocado para usar entrada canalizada em vez de-InputObject
. - O nome do parâmetro
-Pattern
foi omitido deSelect-String
, pois o uso do nome desse parâmetro é opcional. - A opção
-Quiet
foi eliminada deSelect-String
. O filtro ainda funcionará, mas levará mais tempo, poisSelect-String
processará cada arquivo completo em vez de parar após a primeira linha correspondente. -
-eq $true
foi omitido da regra de filtro. Quando um script de filtro já retorna um booleano, você não precisa adicionar um operador de comparação e um objeto se quiser que ele funcione quando o booleano for verdadeiro.- (Observe também que isso funcionará para alguns não-booleanos, como neste script. Aqui, uma correspondência resultará em um objeto de matriz preenchido, que é tratado como verdadeiro, enquanto que um não-correspondência retornará uma matriz vazia que é tratado como falso.)
-
Write-Output
foi omitido. O PowerShell tentará fazer isso como uma ação padrão se um objeto for fornecido sem um comando.
Se você não precisa de todas as propriedades do arquivo, e quer apenas o caminho completo em uma linha antes do conteúdo do arquivo, você pode usar isto:
ls -R|?{$_|Select-String 'dummy'}|%{$_.FullName;gc $_}