2011-08-25 20 views
-1

讓我們先從最近我遇到了一個例子:什麼工具處理柱狀數據中的空間?

C:\>net user 

User accounts for \\SOMESYSTEM 

------------------------------------------------------------------------------- 
ASPNET     user1     AnotherUser123 
Guest     IUSR_SOMESYSTEM   IWAM_SOMESYSTEM 
SUPPORT_12345678   test userrrrrrrrrrrr  test_userrrrrrrrrrrr 
The command completed successfully. 

在第三行,第二列有與空間的登錄。這導致許多基於空白區分字段的工具將該字段視爲兩個字段。

如何處理使用今天的工具以這種方式格式化的數據?

這裏是上,我想在其他現代的跨平臺文字處理工具集已經複製命令提示符純** Windows批處理語言的例子:

C:\>cmd /v:on 
Microsoft Windows [Version 5.2.3790] 
(C) Copyright 1985-2003 Microsoft Corp. 

C:\>echo off 

for /f "skip=4 tokens=*" %g in ('net user ^| findstr /v /c:"The command completed successfully."') do (
More? set record=%g 
More? echo !record:~0,20! 
More? echo !record:~25,20! 
More? echo !record:~50,20! 
More?) 
ASPNET 
user1 
AnotherUser123 
Guest 
IUSR_SOMESYSTEM 
IWAM_SOMESYSTEM 
SUPPORT_12345678 
test userrrrrrrrrrrr 
test_userrrrrrrrrrrr 


echo on 
C:\> 

**使用可變延遲擴展(cmd/v:on或setlocal enabledelayedex擴展在一個批處理文件中),for/f命令輸出解析器和可變子串語法...除了在美妙的網站http://ss64.com/nt/syntax.html

AWK,我沒有看到處理'userrrrrrrrrrr'的方法r'登錄字段,而不使用substr()方法與上面的變量子字符串語法類似。是否有另一種語言使文本變得簡單並且不像sed那樣只寫文本?

+2

「最佳」每次都會讓你陷入麻煩,因爲這是一個意見問題。我會使用我知道的工具,或者我想學習的工具。 – dmckee

+0

是的,「分欄」數據中的空格是一個問題。 'net user'是否允許任何選項爲每個用戶輸出1行?然後使用awk是一塊蛋糕。您是否嘗試過將輸出管道輸出爲awk,可能是autoformatting,因爲它'知道'它將進入屏幕。 'net user | awk'{print $ 0}''將是測試該理論的方式。祝你好運。 – shellter

+0

@shellter不幸的是,網絡用戶並不那麼聰明。你知道哪些工具能很好地處理這種情況?我在柱狀數據中遇到很多提示問題的空間。我希望AWK允許像cut -c這樣的列範圍規範。 – mnestic

回答

-2

perl真的是您的案例和其他數百萬人的最佳選擇。這是非常普遍的,並且網絡已經成熟,並帶有示例和文檔。是的,它跨平臺,非常穩定,跨平臺幾乎完美一致。我幾乎說因爲沒有什麼是完美的,我懷疑你一生中會遇到不一致。

它是一個語言解釋器,但也支持豐富的命令行界面。

+0

「最好的選擇」是主觀的 – ghostdog74

+0

這絕對是主觀的。這裏的意見是不可容忍的嗎? – Jack

+0

perl很爛,R好多了 – mdsumner

0

TEST

printf " 
User accounts for \\SOMESYSTEM 

------------------------------------------------------------------------------- 
ASPNET     user1     AnotherUser123 
Guest     IUSR_SOMESYSTEM   IWAM_SOMESYSTEM 
SUPPORT_12345678   test userrrrrrrrrrrr  test_userrrrrrrrrrrr 
The command completed successfully. 
\n" | awk 'BEGIN{ 
     colWidth=25 
     } 
     /-----/ {next} 
     /^[[:space:]]*$/{next} 
     /^User accounts/{next} 
     /^The command completed/{next} 
     { 
     col1=substr($0,1,colWidth) 
     col2=substr($0,1+colWidth,colWidth) 
     col3=substr($0,1+(colWidth*2),colWidth) 
     printf("%s\n%s\n%s\n", col1, col2, col3) 
     }' 

有可能比1+更好的方法(列表ColWidth * 2),但我沒時間了現在。

如果您嘗試按原樣執行代碼,則必須刪除printf語句中每行前面的前導空格。

我希望這會有所幫助。

1

的PowerShell:

本地用戶列表例如,沒有文本匹配需要

Get-WmiObject Win32_UserAccount | Format-Table -Property Caption -HideTableHeaders 

或者,如果你使用 「NET USER」:只是做一個

$out = net user  # Send stdout to $out 
$out = $out[4..($out.Length-3)]  # Skip header/tail 
[regex]::split($out, "\s{2}") | where { $_.Length -ne 0 } 
# Split on double-space and skip empty lines 
0

直接查詢用戶帳戶,使用vbscript(或者如果您的系統支持powershell)

strComputer = "." 
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") 
Set colItems = objWMIService.ExecQuery("Select * from Win32_UserAccount",,48) 
For Each objItem in colItems 
    Wscript.Echo objItem.Name 
Next 

這將顯示一個用戶列表,每行一個。如果您的目標只是顯示用戶名,則不需要使用其他工具來處理數據。

0

awk對於這個問題並不是那麼好,因爲awk將注意力集中在具有可識別字段分隔符的記錄上,而示例文件使用固定寬度字段。例如,您可以嘗試爲字段分隔符使用正則表達式,但這可能會出錯。正確的方法是使用固定寬度將文件清理成更容易處理的文件; awk可以做到這一點,但它不雅觀。

基本上,這個例子很難,因爲它沒有遵循任何明確的規則。最好的方法是非常通用的方法:使用庫函數以精確定義的格式將數據寫入文件,使用補充庫函數讀取文件。具體的語言與這個策略無關。當你已經有一個像這個例子那樣的文件時,這不會有幫助。

0

對於此部分:

set record=%g 
More? echo !record:~0,20! 
More? echo !record:~25,20! 
More? echo !record:~50,20! 

我會用:

for /f "tokens=1-26 delims= " %a in (%g%) do (
if not "%a" = "" echo %a 
if not "%b" = "" echo %b 
if not "%c" = "" echo %c 
rem ... and so on... 
if not "%y" = "" echo %y 
if not "%z" = "" echo %z 
) 

也就是說,如果我不得不這樣做使用批處理。但根據你的問題,我不敢把這稱爲「現代」。

相關問題